/* Generate code from machine description to recognize rtl as insns.
   Copyright (C) 1987-2021 Free Software Foundation, Inc.

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


/* This program is used to produce insn-recog.c, which contains a
   function called `recog' plus its subroutines.  These functions
   contain a decision tree that recognizes whether an rtx, the
   argument given to recog, is a valid instruction.

   recog returns -1 if the rtx is not valid.  If the rtx is valid,
   recog returns a nonnegative number which is the insn code number
   for the pattern that matched.  This is the same as the order in the
   machine description of the entry that matched.  This number can be
   used as an index into various insn_* tables, such as insn_template,
   insn_outfun, and insn_n_operands (found in insn-output.c).

   The third argument to recog is an optional pointer to an int.  If
   present, recog will accept a pattern if it matches except for
   missing CLOBBER expressions at the end.  In that case, the value
   pointed to by the optional pointer will be set to the number of
   CLOBBERs that need to be added (it should be initialized to zero by
   the caller).  If it is set nonzero, the caller should allocate a
   PARALLEL of the appropriate size, copy the initial entries, and
   call add_clobbers (found in insn-emit.c) to fill in the CLOBBERs.

   This program also generates the function `split_insns', which
   returns 0 if the rtl could not be split, or it returns the split
   rtl as an INSN list.

   This program also generates the function `peephole2_insns', which
   returns 0 if the rtl could not be matched.  If there was a match,
   the new rtl is returned in an INSN list, and LAST_INSN will point
   to the last recognized insn in the old sequence.


   At a high level, the algorithm used in this file is as follows:

   1. Build up a decision tree for each routine, using the following
      approach to matching an rtx:

      - First determine the "shape" of the rtx, based on GET_CODE,
	XVECLEN and XINT.  This phase examines SET_SRCs before SET_DESTs
	since SET_SRCs tend to be more distinctive.  It examines other
	operands in numerical order, since the canonicalization rules
	prefer putting complex operands of commutative operators first.

      - Next check modes and predicates.  This phase examines all
	operands in numerical order, even for SETs, since the mode of a
	SET_DEST is exact while the mode of a SET_SRC can be VOIDmode
	for constant integers.

      - Next check match_dups.

      - Finally check the C condition and (where appropriate) pnum_clobbers.

   2. Try to optimize the tree by removing redundant tests, CSEing tests,
      folding tests together, etc.

   3. Look for common subtrees and split them out into "pattern" routines.
      These common subtrees can be identical or they can differ in mode,
      code, or integer (usually an UNSPEC or UNSPEC_VOLATILE code).
      In the latter case the users of the pattern routine pass the
      appropriate mode, etc., as argument.  For example, if two patterns
      contain:

         (plus:SI (match_operand:SI 1 "register_operand")
	          (match_operand:SI 2 "register_operand"))

      we can split the associated matching code out into a subroutine.
      If a pattern contains:

         (minus:DI (match_operand:DI 1 "register_operand")
	           (match_operand:DI 2 "register_operand"))

      then we can consider using the same matching routine for both
      the plus and minus expressions, passing PLUS and SImode in the
      former case and MINUS and DImode in the latter case.

      The main aim of this phase is to reduce the compile time of the
      insn-recog.c code and to reduce the amount of object code in
      insn-recog.o.

   4. Split the matching trees into functions, trying to limit the
      size of each function to a sensible amount.

      Again, the main aim of this phase is to reduce the compile time
      of insn-recog.c.  (It doesn't help with the size of insn-recog.o.)

   5. Write out C++ code for each function.  */

#include "bconfig.h"
#define INCLUDE_ALGORITHM
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "errors.h"
#include "read-md.h"
#include "gensupport.h"

#undef GENERATOR_FILE
enum true_rtx_doe {
#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) TRUE_##ENUM,
#include "rtl.def"
#undef DEF_RTL_EXPR
  FIRST_GENERATOR_RTX_CODE
};
#define NUM_TRUE_RTX_CODE ((int) FIRST_GENERATOR_RTX_CODE)
#define GENERATOR_FILE 1

/* Debugging variables to control which optimizations are performed.
   Note that disabling merge_states_p leads to very large output.  */
static const bool merge_states_p = true;
static const bool collapse_optional_decisions_p = true;
static const bool cse_tests_p = true;
static const bool simplify_tests_p = true;
static const bool use_operand_variables_p = true;
static const bool use_subroutines_p = true;
static const bool use_pattern_routines_p = true;

/* Whether to add comments for optional tests that we decided to keep.
   Can be useful when debugging the generator itself but is noise when
   debugging the generated code.  */
static const bool mark_optional_transitions_p = false;

/* Whether pattern routines should calculate positions relative to their
   rtx parameter rather than use absolute positions.  This e.g. allows
   a pattern routine to be shared between a plain SET and a PARALLEL
   that includes a SET.

   In principle it sounds like this should be useful, especially for
   recog_for_combine, where the plain SET form is generated automatically
   from a PARALLEL of a single SET and some CLOBBERs.  In practice it doesn't
   seem to help much and leads to slightly bigger object files.  */
static const bool relative_patterns_p = false;

/* Whether pattern routines should be allowed to test whether pnum_clobbers
   is null.  This requires passing pnum_clobbers around as a parameter.  */
static const bool pattern_have_num_clobbers_p = true;

/* Whether pattern routines should be allowed to test .md file C conditions.
   This requires passing insn around as a parameter, in case the C
   condition refers to it.  In practice this tends to lead to bigger
   object files.  */
static const bool pattern_c_test_p = false;

/* Whether to require each parameter passed to a pattern routine to be
   unique.  Disabling this check for example allows unary operators with
   matching modes (like NEG) and unary operators with mismatched modes
   (like ZERO_EXTEND) to be matched by a single pattern.  However, we then
   often have cases where the same value is passed too many times.  */
static const bool force_unique_params_p = true;

/* The maximum (approximate) depth of block nesting that an individual
   routine or subroutine should have.  This limit is about keeping the
   output readable rather than reducing compile time.  */
static const unsigned int MAX_DEPTH = 6;

/* The minimum number of pseudo-statements that a state must have before
   we split it out into a subroutine.  */
static const unsigned int MIN_NUM_STATEMENTS = 5;

/* The number of pseudo-statements a state can have before we consider
   splitting out substates into subroutines.  This limit is about avoiding
   compile-time problems with very big functions (and also about keeping
   functions within --param optimization limits, etc.).  */
static const unsigned int MAX_NUM_STATEMENTS = 200;

/* The minimum number of pseudo-statements that can be used in a pattern
   routine.  */
static const unsigned int MIN_COMBINE_COST = 4;

/* The maximum number of arguments that a pattern routine can have.
   The idea is to prevent one pattern getting a ridiculous number of
   arguments when it would be more beneficial to have a separate pattern
   routine instead.  */
static const unsigned int MAX_PATTERN_PARAMS = 5;

/* The maximum operand number plus one.  */
int num_operands;

/* Ways of obtaining an rtx to be tested.  */
enum position_type {
  /* PATTERN (peep2_next_insn (ARG)).  */
  POS_PEEP2_INSN,

  /* XEXP (BASE, ARG).  */
  POS_XEXP,

  /* XVECEXP (BASE, 0, ARG).  */
  POS_XVECEXP0
};

/* The position of an rtx relative to X0.  Each useful position is
   represented by exactly one instance of this structure.  */
struct position
{
  /* The parent rtx.  This is the root position for POS_PEEP2_INSNs.  */
  struct position *base;

  /* A position with the same BASE and TYPE, but with the next value
     of ARG.  */
  struct position *next;

  /* A list of all POS_XEXP positions that use this one as their base,
     chained by NEXT fields.  The first entry represents XEXP (this, 0),
     the second represents XEXP (this, 1), and so on.  */
  struct position *xexps;

  /* A list of POS_XVECEXP0 positions that use this one as their base,
     chained by NEXT fields.  The first entry represents XVECEXP (this, 0, 0),
     the second represents XVECEXP (this, 0, 1), and so on.  */
  struct position *xvecexp0s;

  /* The type of position.  */
  enum position_type type;

  /* The argument to TYPE (shown as ARG in the position_type comments).  */
  int arg;

  /* The instruction to which the position belongs.  */
  unsigned int insn_id;

  /* The depth of this position relative to the instruction pattern.
     E.g. if the instruction pattern is a SET, the SET itself has a
     depth of 0 while the SET_DEST and SET_SRC have depths of 1.  */
  unsigned int depth;

  /* A unique identifier for this position.  */
  unsigned int id;
};

enum routine_type {
  SUBPATTERN, RECOG, SPLIT, PEEPHOLE2
};

/* The root position (x0).  */
static struct position root_pos;

/* The number of positions created.  Also one higher than the maximum
   position id.  */
static unsigned int num_positions = 1;

/* A list of all POS_PEEP2_INSNs.  The entry for insn 0 is the root position,
   since we are given that instruction's pattern as x0.  */
static struct position *peep2_insn_pos_list = &root_pos;

/* Return a position with the given BASE, TYPE and ARG.  NEXT_PTR
   points to where the unique object that represents the position
   should be stored.  Create the object if it doesn't already exist,
   otherwise reuse the object that is already there.  */

static struct position *
next_position (struct position **next_ptr, struct position *base,
	       enum position_type type, int arg)
{
  struct position *pos;

  pos = *next_ptr;
  if (!pos)
    {
      pos = XCNEW (struct position);
      pos->type = type;
      pos->arg = arg;
      if (type == POS_PEEP2_INSN)
	{
	  pos->base = 0;
	  pos->insn_id = arg;
	  pos->depth = base->depth;
	}
      else
	{
	  pos->base = base;
	  pos->insn_id = base->insn_id;
	  pos->depth = base->depth + 1;
	}
      pos->id = num_positions++;
      *next_ptr = pos;
    }
  return pos;
}

/* Compare positions POS1 and POS2 lexicographically.  */

static int
compare_positions (struct position *pos1, struct position *pos2)
{
  int diff;

  diff = pos1->depth - pos2->depth;
  if (diff < 0)
    do
      pos2 = pos2->base;
    while (pos1->depth != pos2->depth);
  else if (diff > 0)
    do
      pos1 = pos1->base;
    while (pos1->depth != pos2->depth);
  while (pos1 != pos2)
    {
      diff = (int) pos1->type - (int) pos2->type;
      if (diff == 0)
	diff = pos1->arg - pos2->arg;
      pos1 = pos1->base;
      pos2 = pos2->base;
    }
  return diff;
}

/* Return the most deeply-nested position that is common to both
   POS1 and POS2.  If the positions are from different instructions,
   return the one with the lowest insn_id.  */

static struct position *
common_position (struct position *pos1, struct position *pos2)
{
  if (pos1->insn_id != pos2->insn_id)
    return pos1->insn_id < pos2->insn_id ? pos1 : pos2;
  if (pos1->depth > pos2->depth)
    std::swap (pos1, pos2);
  while (pos1->depth != pos2->depth)
    pos2 = pos2->base;
  while (pos1 != pos2)
    {
      pos1 = pos1->base;
      pos2 = pos2->base;
    }
  return pos1;
}

/* Search for and return operand N, stop when reaching node STOP.  */

static rtx
find_operand (rtx pattern, int n, rtx stop)
{
  const char *fmt;
  RTX_CODE code;
  int i, j, len;
  rtx r;

  if (pattern == stop)
    return stop;

  code = GET_CODE (pattern);
  if ((code == MATCH_SCRATCH
       || code == MATCH_OPERAND
       || code == MATCH_OPERATOR
       || code == MATCH_PARALLEL)
      && XINT (pattern, 0) == n)
    return pattern;

  fmt = GET_RTX_FORMAT (code);
  len = GET_RTX_LENGTH (code);
  for (i = 0; i < len; i++)
    {
      switch (fmt[i])
	{
	case 'e': case 'u':
	  if ((r = find_operand (XEXP (pattern, i), n, stop)) != NULL_RTX)
	    return r;
	  break;

	case 'V':
	  if (! XVEC (pattern, i))
	    break;
	  /* Fall through.  */

	case 'E':
	  for (j = 0; j < XVECLEN (pattern, i); j++)
	    if ((r = find_operand (XVECEXP (pattern, i, j), n, stop))
		!= NULL_RTX)
	      return r;
	  break;

	case 'r': case 'p': case 'i': case 'w': case '0': case 's':
	  break;

	default:
	  gcc_unreachable ();
	}
    }

  return NULL;
}

/* Search for and return operand M, such that it has a matching
   constraint for operand N.  */

static rtx
find_matching_operand (rtx pattern, int n)
{
  const char *fmt;
  RTX_CODE code;
  int i, j, len;
  rtx r;

  code = GET_CODE (pattern);
  if (code == MATCH_OPERAND
      && (XSTR (pattern, 2)[0] == '0' + n
	  || (XSTR (pattern, 2)[0] == '%'
	      && XSTR (pattern, 2)[1] == '0' + n)))
    return pattern;

  fmt = GET_RTX_FORMAT (code);
  len = GET_RTX_LENGTH (code);
  for (i = 0; i < len; i++)
    {
      switch (fmt[i])
	{
	case 'e': case 'u':
	  if ((r = find_matching_operand (XEXP (pattern, i), n)))
	    return r;
	  break;

	case 'V':
	  if (! XVEC (pattern, i))
	    break;
	  /* Fall through.  */

	case 'E':
	  for (j = 0; j < XVECLEN (pattern, i); j++)
	    if ((r = find_matching_operand (XVECEXP (pattern, i, j), n)))
	      return r;
	  break;

	case 'r': case 'p': case 'i': case 'w': case '0': case 's':
	  break;

	default:
	  gcc_unreachable ();
	}
    }

  return NULL;
}

/* In DEFINE_EXPAND, DEFINE_SPLIT, and DEFINE_PEEPHOLE2, we
   don't use the MATCH_OPERAND constraint, only the predicate.
   This is confusing to folks doing new ports, so help them
   not make the mistake.  */

static bool
constraints_supported_in_insn_p (rtx insn)
{
  return !(GET_CODE (insn) == DEFINE_EXPAND
	   || GET_CODE (insn) == DEFINE_SPLIT
	   || GET_CODE (insn) == DEFINE_PEEPHOLE2);
}

/* Return the name of the predicate matched by MATCH_RTX.  */

static const char *
predicate_name (rtx match_rtx)
{
  if (GET_CODE (match_rtx) == MATCH_SCRATCH)
    return "scratch_operand";
  else
    return XSTR (match_rtx, 1);
}

/* Return true if OPERAND is a MATCH_OPERAND using a special predicate
   function.  */

static bool
special_predicate_operand_p (rtx operand)
{
  if (GET_CODE (operand) == MATCH_OPERAND)
    {
      const char *pred_name = predicate_name (operand);
      if (pred_name[0] != 0)
	{
	  const struct pred_data *pred;

	  pred = lookup_predicate (pred_name);
	  return pred != NULL && pred->special;
	}
    }

  return false;
}

/* Check for various errors in PATTERN, which is part of INFO.
   SET is nonnull for a destination, and is the complete set pattern.
   SET_CODE is '=' for normal sets, and '+' within a context that
   requires in-out constraints.  */

static void
validate_pattern (rtx pattern, md_rtx_info *info, rtx set, int set_code)
{
  const char *fmt;
  RTX_CODE code;
  size_t i, len;
  int j;

  code = GET_CODE (pattern);
  switch (code)
    {
    case MATCH_SCRATCH:
      {
	const char constraints0 = XSTR (pattern, 1)[0];

	if (!constraints_supported_in_insn_p (info->def))
	  {
	    if (constraints0)
	      {
		error_at (info->loc, "constraints not supported in %s",
			  GET_RTX_NAME (GET_CODE (info->def)));
	      }
	    return;
	  }

	/* If a MATCH_SCRATCH is used in a context requiring an write-only
	   or read/write register, validate that.  */
	if (set_code == '='
	    && constraints0
	    && constraints0 != '='
	    && constraints0 != '+')
	  {
	    error_at (info->loc, "operand %d missing output reload",
		      XINT (pattern, 0));
	  }
	return;
      }
    case MATCH_DUP:
    case MATCH_OP_DUP:
    case MATCH_PAR_DUP:
      if (find_operand (info->def, XINT (pattern, 0), pattern) == pattern)
	error_at (info->loc, "operand %i duplicated before defined",
		  XINT (pattern, 0));
      break;
    case MATCH_OPERAND:
    case MATCH_OPERATOR:
      {
	const char *pred_name = XSTR (pattern, 1);
	const struct pred_data *pred;
	const char *c_test;

	c_test = get_c_test (info->def);

	if (pred_name[0] != 0)
	  {
	    pred = lookup_predicate (pred_name);
	    if (!pred)
	      error_at (info->loc, "unknown predicate '%s'", pred_name);
	  }
	else
	  pred = 0;

	if (code == MATCH_OPERAND)
	  {
	    const char *constraints = XSTR (pattern, 2);
	    const char constraints0 = constraints[0];

	    if (!constraints_supported_in_insn_p (info->def))
	      {
		if (constraints0)
		  {
		    error_at (info->loc, "constraints not supported in %s",
			      GET_RTX_NAME (GET_CODE (info->def)));
		  }
	      }

	    /* A MATCH_OPERAND that is a SET should have an output reload.  */
	    else if (set && constraints0)
	      {
		if (set_code == '+')
		  {
		    if (constraints0 == '+')
		      ;
		    /* If we've only got an output reload for this operand,
		       we'd better have a matching input operand.  */
		    else if (constraints0 == '='
			     && find_matching_operand (info->def,
						       XINT (pattern, 0)))
		      ;
		    else
		      error_at (info->loc, "operand %d missing in-out reload",
				XINT (pattern, 0));
		  }
		else if (constraints0 != '=' && constraints0 != '+')
		  error_at (info->loc, "operand %d missing output reload",
			    XINT (pattern, 0));
	      }

	    /* For matching constraint in MATCH_OPERAND, the digit must be a
	       smaller number than the number of the operand that uses it in the
	       constraint.  */
	    while (1)
	      {
		while (constraints[0]
		       && (constraints[0] == ' ' || constraints[0] == ','))
		  constraints++;
		if (!constraints[0])
		  break;

		if (constraints[0] >= '0' && constraints[0] <= '9')
		  {
		    int val;

		    sscanf (constraints, "%d", &val);
		    if (val >= XINT (pattern, 0))
		      error_at (info->loc, "constraint digit %d is not"
				" smaller than operand %d",
				val, XINT (pattern, 0));
		  }

		while (constraints[0] && constraints[0] != ',')
		  constraints++;
	      }
	  }

	/* Allowing non-lvalues in destinations -- particularly CONST_INT --
	   while not likely to occur at runtime, results in less efficient
	   code from insn-recog.c.  */
	if (set && pred && pred->allows_non_lvalue)
	  error_at (info->loc, "destination operand %d allows non-lvalue",
		    XINT (pattern, 0));

	/* A modeless MATCH_OPERAND can be handy when we can check for
	   multiple modes in the c_test.  In most other cases, it is a
	   mistake.  Only DEFINE_INSN is eligible, since SPLIT and
	   PEEP2 can FAIL within the output pattern.  Exclude special
	   predicates, which check the mode themselves.  Also exclude
	   predicates that allow only constants.  Exclude the SET_DEST
	   of a call instruction, as that is a common idiom.  */

	if (GET_MODE (pattern) == VOIDmode
	    && code == MATCH_OPERAND
	    && GET_CODE (info->def) == DEFINE_INSN
	    && pred
	    && !pred->special
	    && pred->allows_non_const
	    && strstr (c_test, "operands") == NULL
	    && ! (set
		  && GET_CODE (set) == SET
		  && GET_CODE (SET_SRC (set)) == CALL))
	  message_at (info->loc, "warning: operand %d missing mode?",
		      XINT (pattern, 0));
	return;
      }

    case SET:
      {
	machine_mode dmode, smode;
	rtx dest, src;

	dest = SET_DEST (pattern);
	src = SET_SRC (pattern);

	/* STRICT_LOW_PART is a wrapper.  Its argument is the real
	   destination, and it's mode should match the source.  */
	if (GET_CODE (dest) == STRICT_LOW_PART)
	  dest = XEXP (dest, 0);

	/* Find the referent for a DUP.  */

	if (GET_CODE (dest) == MATCH_DUP
	    || GET_CODE (dest) == MATCH_OP_DUP
	    || GET_CODE (dest) == MATCH_PAR_DUP)
	  dest = find_operand (info->def, XINT (dest, 0), NULL);

	if (GET_CODE (src) == MATCH_DUP
	    || GET_CODE (src) == MATCH_OP_DUP
	    || GET_CODE (src) == MATCH_PAR_DUP)
	  src = find_operand (info->def, XINT (src, 0), NULL);

	dmode = GET_MODE (dest);
	smode = GET_MODE (src);

	/* Mode checking is not performed for special predicates.  */
	if (special_predicate_operand_p (src)
	    || special_predicate_operand_p (dest))
	  ;

        /* The operands of a SET must have the same mode unless one
	   is VOIDmode.  */
        else if (dmode != VOIDmode && smode != VOIDmode && dmode != smode)
	  error_at (info->loc, "mode mismatch in set: %smode vs %smode",
		    GET_MODE_NAME (dmode), GET_MODE_NAME (smode));

	/* If only one of the operands is VOIDmode, and PC or CC0 is
	   not involved, it's probably a mistake.  */
	else if (dmode != smode
		 && GET_CODE (dest) != PC
		 && GET_CODE (dest) != CC0
		 && GET_CODE (src) != PC
		 && GET_CODE (src) != CC0
		 && !CONST_INT_P (src)
		 && !CONST_WIDE_INT_P (src)
		 && GET_CODE (src) != CALL)
	  {
	    const char *which;
	    which = (dmode == VOIDmode ? "destination" : "source");
	    message_at (info->loc, "warning: %s missing a mode?", which);
	  }

	if (dest != SET_DEST (pattern))
	  validate_pattern (dest, info, pattern, '=');
	validate_pattern (SET_DEST (pattern), info, pattern, '=');
        validate_pattern (SET_SRC (pattern), info, NULL_RTX, 0);
        return;
      }

    case CLOBBER:
      validate_pattern (SET_DEST (pattern), info, pattern, '=');
      return;

    case ZERO_EXTRACT:
      validate_pattern (XEXP (pattern, 0), info, set, set ? '+' : 0);
      validate_pattern (XEXP (pattern, 1), info, NULL_RTX, 0);
      validate_pattern (XEXP (pattern, 2), info, NULL_RTX, 0);
      return;

    case STRICT_LOW_PART:
      validate_pattern (XEXP (pattern, 0), info, set, set ? '+' : 0);
      return;

    case LABEL_REF:
      if (GET_MODE (XEXP (pattern, 0)) != VOIDmode)
	error_at (info->loc, "operand to label_ref %smode not VOIDmode",
		  GET_MODE_NAME (GET_MODE (XEXP (pattern, 0))));
      break;

    case VEC_SELECT:
      if (GET_MODE (pattern) != VOIDmode)
	{
	  machine_mode mode = GET_MODE (pattern);
	  machine_mode imode = GET_MODE (XEXP (pattern, 0));
	  machine_mode emode
	    = VECTOR_MODE_P (mode) ? GET_MODE_INNER (mode) : mode;
	  if (GET_CODE (XEXP (pattern, 1)) == PARALLEL)
	    {
	      int expected = 1;
	      unsigned int nelems;
	      if (VECTOR_MODE_P (mode)
		  && !GET_MODE_NUNITS (mode).is_constant (&expected))
		error_at (info->loc,
			  "vec_select with variable-sized mode %s",
			  GET_MODE_NAME (mode));
	      else if (XVECLEN (XEXP (pattern, 1), 0) != expected)
		error_at (info->loc,
			  "vec_select parallel with %d elements, expected %d",
			  XVECLEN (XEXP (pattern, 1), 0), expected);
	      else if (VECTOR_MODE_P (imode)
		       && GET_MODE_NUNITS (imode).is_constant (&nelems))
		{
		  int i;
		  for (i = 0; i < expected; ++i)
		    if (CONST_INT_P (XVECEXP (XEXP (pattern, 1), 0, i))
			&& (UINTVAL (XVECEXP (XEXP (pattern, 1), 0, i))
			    >= nelems))
		      error_at (info->loc,
				"out of bounds selector %u in vec_select, "
				"expected at most %u",
				(unsigned)
				UINTVAL (XVECEXP (XEXP (pattern, 1), 0, i)),
				nelems - 1);
		}
	    }
	  if (imode != VOIDmode && !VECTOR_MODE_P (imode))
	    error_at (info->loc, "%smode of first vec_select operand is not a "
				 "vector mode", GET_MODE_NAME (imode));
	  else if (imode != VOIDmode && GET_MODE_INNER (imode) != emode)
	    error_at (info->loc, "element mode mismatch between vec_select "
				 "%smode and its operand %smode",
		      GET_MODE_NAME (emode),
		      GET_MODE_NAME (GET_MODE_INNER (imode)));
	}
      break;

    default:
      break;
    }

  fmt = GET_RTX_FORMAT (code);
  len = GET_RTX_LENGTH (code);
  for (i = 0; i < len; i++)
    {
      switch (fmt[i])
	{
	case 'e': case 'u':
	  validate_pattern (XEXP (pattern, i), info, NULL_RTX, 0);
	  break;

	case 'E':
	  for (j = 0; j < XVECLEN (pattern, i); j++)
	    validate_pattern (XVECEXP (pattern, i, j), info, NULL_RTX, 0);
	  break;

	case 'r': case 'p': case 'i': case 'w': case '0': case 's':
	  break;

	default:
	  gcc_unreachable ();
	}
    }
}

/* Simple list structure for items of type T, for use when being part
   of a list is an inherent property of T.  T must have members equivalent
   to "T *prev, *next;" and a function "void set_parent (list_head <T> *)"
   to set the parent list.  */
template <typename T>
class list_head
{
public:
  /* A range of linked items.  */
  class range
  {
  public:
    range (T *);
    range (T *, T *);

    T *start, *end;
    void set_parent (list_head *);
  };

  list_head ();
  range release ();
  void push_back (range);
  range remove (range);
  void replace (range, range);
  T *singleton () const;

  T *first, *last;
};

/* Create a range [START_IN, START_IN].  */

template <typename T>
list_head <T>::range::range (T *start_in) : start (start_in), end (start_in) {}

/* Create a range [START_IN, END_IN], linked by next and prev fields.  */

template <typename T>
list_head <T>::range::range (T *start_in, T *end_in)
  : start (start_in), end (end_in) {}

template <typename T>
void
list_head <T>::range::set_parent (list_head <T> *owner)
{
  for (T *item = start; item != end; item = item->next)
    item->set_parent (owner);
  end->set_parent (owner);
}

template <typename T>
list_head <T>::list_head () : first (0), last (0) {}

/* Add R to the end of the list.  */

template <typename T>
void
list_head <T>::push_back (range r)
{
  if (last)
    last->next = r.start;
  else
    first = r.start;
  r.start->prev = last;
  last = r.end;
  r.set_parent (this);
}

/* Remove R from the list.  R remains valid and can be inserted into
   other lists.  */

template <typename T>
typename list_head <T>::range
list_head <T>::remove (range r)
{
  if (r.start->prev)
    r.start->prev->next = r.end->next;
  else
    first = r.end->next;
  if (r.end->next)
    r.end->next->prev = r.start->prev;
  else
    last = r.start->prev;
  r.start->prev = 0;
  r.end->next = 0;
  r.set_parent (0);
  return r;
}

/* Replace OLDR with NEWR.  OLDR remains valid and can be inserted into
   other lists.  */

template <typename T>
void
list_head <T>::replace (range oldr, range newr)
{
  newr.start->prev = oldr.start->prev;
  newr.end->next = oldr.end->next;

  oldr.start->prev = 0;
  oldr.end->next = 0;
  oldr.set_parent (0);

  if (newr.start->prev)
    newr.start->prev->next = newr.start;
  else
    first = newr.start;
  if (newr.end->next)
    newr.end->next->prev = newr.end;
  else
    last = newr.end;
  newr.set_parent (this);
}

/* Empty the list and return the previous contents as a range that can
   be inserted into other lists.  */

template <typename T>
typename list_head <T>::range
list_head <T>::release ()
{
  range r (first, last);
  first = 0;
  last = 0;
  r.set_parent (0);
  return r;
}

/* If the list contains a single item, return that item, otherwise return
   null.  */

template <typename T>
T *
list_head <T>::singleton () const
{
  return first == last ? first : 0;
}

class state;

/* Describes a possible successful return from a routine.  */
struct acceptance_type
{
  /* The type of routine we're returning from.  */
  routine_type type : 16;

  /* True if this structure only really represents a partial match,
     and if we must call a subroutine of type TYPE to complete the match.
     In this case we'll call the subroutine and, if it succeeds, return
     whatever the subroutine returned.

     False if this structure presents a full match.  */
  unsigned int partial_p : 1;

  union
  {
    /* If PARTIAL_P, this is the number of the subroutine to call.  */
    int subroutine_id;

    /* Valid if !PARTIAL_P.  */
    struct
    {
      /* The identifier of the matching pattern.  For SUBPATTERNs this
	 value belongs to an ad-hoc routine-specific enum.  For the
	 others it's the number of an .md file pattern.  */
      int code;
      union
      {
	/* For RECOG, the number of clobbers that must be added to the
	   pattern in order for it to match CODE.  */
	int num_clobbers;

	/* For PEEPHOLE2, the number of additional instructions that were
	   included in the optimization.  */
	int match_len;
      } u;
    } full;
  } u;
};

bool
operator == (const acceptance_type &a, const acceptance_type &b)
{
  if (a.partial_p != b.partial_p)
    return false;
  if (a.partial_p)
    return a.u.subroutine_id == b.u.subroutine_id;
  else
    return a.u.full.code == b.u.full.code;
}

bool
operator != (const acceptance_type &a, const acceptance_type &b)
{
  return !operator == (a, b);
}

/* Represents a parameter to a pattern routine.  */
class parameter
{
public:
  /* The C type of parameter.  */
  enum type_enum {
    /* Represents an invalid parameter.  */
    UNSET,

    /* A machine_mode parameter.  */
    MODE,

    /* An rtx_code parameter.  */
    CODE,

    /* An int parameter.  */
    INT,

    /* An unsigned int parameter.  */
    UINT,

    /* A HOST_WIDE_INT parameter.  */
    WIDE_INT
  };

  parameter ();
  parameter (type_enum, bool, uint64_t);

  /* The type of the parameter.  */
  type_enum type;

  /* True if the value passed is variable, false if it is constant.  */
  bool is_param;

  /* If IS_PARAM, this is the number of the variable passed, for an "i%d"
     format string.  If !IS_PARAM, this is the constant value passed.  */
  uint64_t value;
};

parameter::parameter ()
  : type (UNSET), is_param (false), value (0) {}

parameter::parameter (type_enum type_in, bool is_param_in, uint64_t value_in)
  : type (type_in), is_param (is_param_in), value (value_in) {}

bool
operator == (const parameter &param1, const parameter &param2)
{
  return (param1.type == param2.type
	  && param1.is_param == param2.is_param
	  && param1.value == param2.value);
}

bool
operator != (const parameter &param1, const parameter &param2)
{
  return !operator == (param1, param2);
}

/* Represents a routine that matches a partial rtx pattern, returning
   an ad-hoc enum value on success and -1 on failure.  The routine can
   be used by any subroutine type.  The match can be parameterized by
   things like mode, code and UNSPEC number.  */
class pattern_routine
{
public:
  /* The state that implements the pattern.  */
  state *s;

  /* The deepest root position from which S can access all the rtxes it needs.
     This is NULL if the pattern doesn't need an rtx input, usually because
     all matching is done on operands[] instead.  */
  position *pos;

  /* A unique identifier for the routine.  */
  unsigned int pattern_id;

  /* True if the routine takes pnum_clobbers as argument.  */
  bool pnum_clobbers_p;

  /* True if the routine takes the enclosing instruction as argument.  */
  bool insn_p;

  /* The types of the other parameters to the routine, if any.  */
  auto_vec <parameter::type_enum, MAX_PATTERN_PARAMS> param_types;
};

/* All defined patterns.  */
static vec <pattern_routine *> patterns;

/* Represents one use of a pattern routine.  */
class pattern_use
{
public:
  /* The pattern routine to use.  */
  pattern_routine *routine;

  /* The values to pass as parameters.  This vector has the same length
     as ROUTINE->PARAM_TYPES.  */
  auto_vec <parameter, MAX_PATTERN_PARAMS> params;
};

/* Represents a test performed by a decision.  */
class rtx_test
{
public:
  rtx_test ();

  /* The types of test that can be performed.  Most of them take as input
     an rtx X.  Some also take as input a transition label LABEL; the others
     are booleans for which the transition label is always "true".

     The order of the enum isn't important.  */
  enum kind_enum {
    /* Check GET_CODE (X) == LABEL.  */
    CODE,

    /* Check GET_MODE (X) == LABEL.  */
    MODE,

    /* Check REGNO (X) == LABEL.  */
    REGNO_FIELD,

    /* Check known_eq (SUBREG_BYTE (X), LABEL).  */
    SUBREG_FIELD,

    /* Check XINT (X, u.opno) == LABEL.  */
    INT_FIELD,

    /* Check XWINT (X, u.opno) == LABEL.  */
    WIDE_INT_FIELD,

    /* Check XVECLEN (X, 0) == LABEL.  */
    VECLEN,

    /* Check peep2_current_count >= u.min_len.  */
    PEEP2_COUNT,

    /* Check XVECLEN (X, 0) >= u.min_len.  */
    VECLEN_GE,

    /* Check whether X is a cached const_int with value u.integer.  */
    SAVED_CONST_INT,

    /* Check u.predicate.data (X, u.predicate.mode).  */
    PREDICATE,

    /* Check rtx_equal_p (X, operands[u.opno]).  */
    DUPLICATE,

    /* Check whether X matches pattern u.pattern.  */
    PATTERN,

    /* Check whether pnum_clobbers is nonnull (RECOG only).  */
    HAVE_NUM_CLOBBERS,

    /* Check whether general C test u.string holds.  In general the condition
       needs access to "insn" and the full operand list.  */
    C_TEST,

    /* Execute operands[u.opno] = X.  (Always succeeds.)  */
    SET_OP,

    /* Accept u.acceptance.  Always succeeds for SUBPATTERN, RECOG and SPLIT.
       May fail for PEEPHOLE2 if the define_peephole2 C code executes FAIL.  */
    ACCEPT
  };

  /* The position of rtx X in the above description, relative to the
     incoming instruction "insn".  The position is null if the test
     doesn't take an X as input.  */
  position *pos;

  /* Which element of operands[] already contains POS, or -1 if no element
     is known to hold POS.  */
  int pos_operand;

  /* The type of test and its parameters, as described above.  */
  kind_enum kind;
  union
  {
    int opno;
    int min_len;
    struct
    {
      bool is_param;
      int value;
    } integer;
    struct
    {
      const struct pred_data *data;
      /* True if the mode is taken from a machine_mode parameter
	 to the routine rather than a constant machine_mode.  If true,
	 MODE is the number of the parameter (for an "i%d" format string),
	 otherwise it is the mode itself.  */
      bool mode_is_param;
      unsigned int mode;
    } predicate;
    pattern_use *pattern;
    const char *string;
    acceptance_type acceptance;
  } u;

  static rtx_test code (position *);
  static rtx_test mode (position *);
  static rtx_test regno_field (position *);
  static rtx_test subreg_field (position *);
  static rtx_test int_field (position *, int);
  static rtx_test wide_int_field (position *, int);
  static rtx_test veclen (position *);
  static rtx_test peep2_count (int);
  static rtx_test veclen_ge (position *, int);
  static rtx_test predicate (position *, const pred_data *, machine_mode);
  static rtx_test duplicate (position *, int);
  static rtx_test pattern (position *, pattern_use *);
  static rtx_test have_num_clobbers ();
  static rtx_test c_test (const char *);
  static rtx_test set_op (position *, int);
  static rtx_test accept (const acceptance_type &);

  bool terminal_p () const;
  bool single_outcome_p () const;

private:
  rtx_test (position *, kind_enum);
};

rtx_test::rtx_test () {}

rtx_test::rtx_test (position *pos_in, kind_enum kind_in)
  : pos (pos_in), pos_operand (-1), kind (kind_in) {}

rtx_test
rtx_test::code (position *pos)
{
  return rtx_test (pos, rtx_test::CODE);
}

rtx_test
rtx_test::mode (position *pos)
{
  return rtx_test (pos, rtx_test::MODE);
}

rtx_test
rtx_test::regno_field (position *pos)
{
  rtx_test res (pos, rtx_test::REGNO_FIELD);
  return res;
}

rtx_test
rtx_test::subreg_field (position *pos)
{
  rtx_test res (pos, rtx_test::SUBREG_FIELD);
  return res;
}

rtx_test
rtx_test::int_field (position *pos, int opno)
{
  rtx_test res (pos, rtx_test::INT_FIELD);
  res.u.opno = opno;
  return res;
}

rtx_test
rtx_test::wide_int_field (position *pos, int opno)
{
  rtx_test res (pos, rtx_test::WIDE_INT_FIELD);
  res.u.opno = opno;
  return res;
}

rtx_test
rtx_test::veclen (position *pos)
{
  return rtx_test (pos, rtx_test::VECLEN);
}

rtx_test
rtx_test::peep2_count (int min_len)
{
  rtx_test res (0, rtx_test::PEEP2_COUNT);
  res.u.min_len = min_len;
  return res;
}

rtx_test
rtx_test::veclen_ge (position *pos, int min_len)
{
  rtx_test res (pos, rtx_test::VECLEN_GE);
  res.u.min_len = min_len;
  return res;
}

rtx_test
rtx_test::predicate (position *pos, const struct pred_data *data,
		     machine_mode mode)
{
  rtx_test res (pos, rtx_test::PREDICATE);
  res.u.predicate.data = data;
  res.u.predicate.mode_is_param = false;
  res.u.predicate.mode = mode;
  return res;
}

rtx_test
rtx_test::duplicate (position *pos, int opno)
{
  rtx_test res (pos, rtx_test::DUPLICATE);
  res.u.opno = opno;
  return res;
}

rtx_test
rtx_test::pattern (position *pos, pattern_use *pattern)
{
  rtx_test res (pos, rtx_test::PATTERN);
  res.u.pattern = pattern;
  return res;
}

rtx_test
rtx_test::have_num_clobbers ()
{
  return rtx_test (0, rtx_test::HAVE_NUM_CLOBBERS);
}

rtx_test
rtx_test::c_test (const char *string)
{
  rtx_test res (0, rtx_test::C_TEST);
  res.u.string = string;
  return res;
}

rtx_test
rtx_test::set_op (position *pos, int opno)
{
  rtx_test res (pos, rtx_test::SET_OP);
  res.u.opno = opno;
  return res;
}

rtx_test
rtx_test::accept (const acceptance_type &acceptance)
{
  rtx_test res (0, rtx_test::ACCEPT);
  res.u.acceptance = acceptance;
  return res;
}

/* Return true if the test represents an unconditionally successful match.  */

bool
rtx_test::terminal_p () const
{
  return kind == rtx_test::ACCEPT && u.acceptance.type != PEEPHOLE2;
}

/* Return true if the test is a boolean that is always true.  */

bool
rtx_test::single_outcome_p () const
{
  return terminal_p () || kind == rtx_test::SET_OP;
}

bool
operator == (const rtx_test &a, const rtx_test &b)
{
  if (a.pos != b.pos || a.kind != b.kind)
    return false;
  switch (a.kind)
    {
    case rtx_test::CODE:
    case rtx_test::MODE:
    case rtx_test::REGNO_FIELD:
    case rtx_test::SUBREG_FIELD:
    case rtx_test::VECLEN:
    case rtx_test::HAVE_NUM_CLOBBERS:
      return true;

    case rtx_test::PEEP2_COUNT:
    case rtx_test::VECLEN_GE:
      return a.u.min_len == b.u.min_len;

    case rtx_test::INT_FIELD:
    case rtx_test::WIDE_INT_FIELD:
    case rtx_test::DUPLICATE:
    case rtx_test::SET_OP:
      return a.u.opno == b.u.opno;

    case rtx_test::SAVED_CONST_INT:
      return (a.u.integer.is_param == b.u.integer.is_param
	      && a.u.integer.value == b.u.integer.value);

    case rtx_test::PREDICATE:
      return (a.u.predicate.data == b.u.predicate.data
	      && a.u.predicate.mode_is_param == b.u.predicate.mode_is_param
	      && a.u.predicate.mode == b.u.predicate.mode);

    case rtx_test::PATTERN:
      return (a.u.pattern->routine == b.u.pattern->routine
	      && a.u.pattern->params == b.u.pattern->params);

    case rtx_test::C_TEST:
      return strcmp (a.u.string, b.u.string) == 0;

    case rtx_test::ACCEPT:
      return a.u.acceptance == b.u.acceptance;
    }
  gcc_unreachable ();
}

bool
operator != (const rtx_test &a, const rtx_test &b)
{
  return !operator == (a, b);
}

/* A simple set of transition labels.  Most transitions have a singleton
   label, so try to make that case as efficient as possible.  */
class int_set : public auto_vec <uint64_t, 1>
{
public:
  typedef uint64_t *iterator;

  int_set ();
  int_set (uint64_t);
  int_set (const int_set &);

  int_set &operator = (const int_set &);

  iterator begin ();
  iterator end ();
};

int_set::int_set () : auto_vec<uint64_t, 1> () {}

int_set::int_set (uint64_t label) :
  auto_vec<uint64_t, 1> ()
{
  safe_push (label);
}

int_set::int_set (const int_set &other) :
  auto_vec<uint64_t, 1> ()
{
  safe_splice (other);
}

int_set &
int_set::operator = (const int_set &other)
{
  truncate (0);
  safe_splice (other);
  return *this;
}

int_set::iterator
int_set::begin ()
{
  return address ();
}

int_set::iterator
int_set::end ()
{
  return address () + length ();
}

bool
operator == (const int_set &a, const int_set &b)
{
  if (a.length () != b.length ())
    return false;
  for (unsigned int i = 0; i < a.length (); ++i)
    if (a[i] != b[i])
      return false;
  return true;
}

bool
operator != (const int_set &a, const int_set &b)
{
  return !operator == (a, b);
}

class decision;

/* Represents a transition between states, dependent on the result of
   a test T.  */
class transition
{
public:
  transition (const int_set &, state *, bool);

  void set_parent (list_head <transition> *);

  /* Links to other transitions for T.  Always null for boolean tests.  */
  transition *prev, *next;

  /* The transition should be taken when T has one of these values.
     E.g. for rtx_test::CODE this is a set of codes, while for booleans like
     rtx_test::PREDICATE it is always a singleton "true".  The labels are
     sorted in ascending order.  */
  int_set labels;

  /* The source decision.  */
  decision *from;

  /* The target state.  */
  state *to;

  /* True if TO would function correctly even if TEST wasn't performed.
     E.g. it isn't necessary to check whether GET_MODE (x1) is SImode
     before calling register_operand (x1, SImode), since register_operand
     performs its own mode check.  However, checking GET_MODE can be a cheap
     way of disambiguating SImode and DImode register operands.  */
  bool optional;

  /* True if LABELS contains parameter numbers rather than constants.
     E.g. if this is true for a rtx_test::CODE, the label is the number
     of an rtx_code parameter rather than an rtx_code itself.
     LABELS is always a singleton when this variable is true.  */
  bool is_param;
};

/* Represents a test and the action that should be taken on the result.
   If a transition exists for the test outcome, the machine switches
   to the transition's target state.  If no suitable transition exists,
   the machine either falls through to the next decision or, if there are no
   more decisions to try, fails the match.  */
class decision : public list_head <transition>
{
public:
  decision (const rtx_test &);

  void set_parent (list_head <decision> *s);
  bool if_statement_p (uint64_t * = 0) const;

  /* The state to which this decision belongs.  */
  state *s;

  /* Links to other decisions in the same state.  */
  decision *prev, *next;

  /* The test to perform.  */
  rtx_test test;
};

/* Represents one machine state.  For each state the machine tries a list
   of decisions, in order, and acts on the first match.  It fails without
   further backtracking if no decisions match.  */
class state : public list_head <decision>
{
public:
  void set_parent (list_head <state> *) {}
};

transition::transition (const int_set &labels_in, state *to_in,
			bool optional_in)
  : prev (0), next (0), labels (labels_in), from (0), to (to_in),
    optional (optional_in), is_param (false) {}

/* Set the source decision of the transition.  */

void
transition::set_parent (list_head <transition> *from_in)
{
  from = static_cast <decision *> (from_in);
}

decision::decision (const rtx_test &test_in)
  : prev (0), next (0), test (test_in) {}

/* Set the state to which this decision belongs.  */

void
decision::set_parent (list_head <decision> *s_in)
{
  s = static_cast <state *> (s_in);
}

/* Return true if the decision has a single transition with a single label.
   If so, return the label in *LABEL if nonnull.  */

inline bool
decision::if_statement_p (uint64_t *label) const
{
  if (singleton () && first->labels.length () == 1)
    {
      if (label)
	*label = first->labels[0];
      return true;
    }
  return false;
}

/* Add to FROM a decision that performs TEST and has a single transition
   TRANS.  */

static void
add_decision (state *from, const rtx_test &test, transition *trans)
{
  decision *d = new decision (test);
  from->push_back (d);
  d->push_back (trans);
}

/* Add a transition from FROM to a new, empty state that is taken
   when TEST == LABELS.  OPTIONAL says whether the new transition
   should be optional.  Return the new state.  */

static state *
add_decision (state *from, const rtx_test &test, int_set labels, bool optional)
{
  state *to = new state;
  add_decision (from, test, new transition (labels, to, optional));
  return to;
}

/* Insert a decision before decisions R to make them dependent on
   TEST == LABELS.  OPTIONAL says whether the new transition should be
   optional.  */

static decision *
insert_decision_before (state::range r, const rtx_test &test,
			const int_set &labels, bool optional)
{
  decision *newd = new decision (test);
  state *news = new state;
  newd->push_back (new transition (labels, news, optional));
  r.start->s->replace (r, newd);
  news->push_back (r);
  return newd;
}

/* Remove any optional transitions from S that turned out not to be useful.  */

static void
collapse_optional_decisions (state *s)
{
  decision *d = s->first;
  while (d)
    {
      decision *next = d->next;
      for (transition *trans = d->first; trans; trans = trans->next)
	collapse_optional_decisions (trans->to);
      /* A decision with a single optional transition doesn't help
	 partition the potential matches and so is unlikely to be
	 worthwhile.  In particular, if the decision that performs the
	 test is the last in the state, the best it could do is reject
	 an invalid pattern slightly earlier.  If instead the decision
	 is not the last in the state, the condition it tests could hold
	 even for the later decisions in the state.  The best it can do
	 is save work in some cases where only the later decisions can
	 succeed.

	 In both cases the optional transition would add extra work to
	 successful matches when the tested condition holds.  */
      if (transition *trans = d->singleton ())
	if (trans->optional)
	  s->replace (d, trans->to->release ());
      d = next;
    }
}

/* Try to squash several separate tests into simpler ones.  */

static void
simplify_tests (state *s)
{
  for (decision *d = s->first; d; d = d->next)
    {
      uint64_t label;
      /* Convert checks for GET_CODE (x) == CONST_INT and XWINT (x, 0) == N
	 into checks for const_int_rtx[N'], if N is suitably small.  */
      if (d->test.kind == rtx_test::CODE
	  && d->if_statement_p (&label)
	  && label == CONST_INT)
	if (decision *second = d->first->to->singleton ())
	  if (d->test.pos == second->test.pos
	      && second->test.kind == rtx_test::WIDE_INT_FIELD
	      && second->test.u.opno == 0
	      && second->if_statement_p (&label)
	      && IN_RANGE (int64_t (label),
			   -MAX_SAVED_CONST_INT, MAX_SAVED_CONST_INT))
	    {
	      d->test.kind = rtx_test::SAVED_CONST_INT;
	      d->test.u.integer.is_param = false;
	      d->test.u.integer.value = label;
	      d->replace (d->first, second->release ());
	      d->first->labels[0] = true;
	    }
      /* If we have a CODE test followed by a PREDICATE test, rely on
	 the predicate to test the code.

	 This case exists for match_operators.  We initially treat the
	 CODE test for a match_operator as non-optional so that we can
	 safely move down to its operands.  It may turn out that all
	 paths that reach that code test require the same predicate
	 to be true.  cse_tests will then put the predicate test in
	 series with the code test.  */
      if (d->test.kind == rtx_test::CODE)
	if (transition *trans = d->singleton ())
	  {
	    state *s = trans->to;
	    while (decision *d2 = s->singleton ())
	      {
		if (d->test.pos != d2->test.pos)
		  break;
		transition *trans2 = d2->singleton ();
		if (!trans2)
		  break;
		if (d2->test.kind == rtx_test::PREDICATE)
		  {
		    d->test = d2->test;
		    trans->labels = int_set (true);
		    s->replace (d2, trans2->to->release ());
		    break;
		  }
		s = trans2->to;
	      }
	  }
      for (transition *trans = d->first; trans; trans = trans->next)
	simplify_tests (trans->to);
    }
}

/* Return true if all successful returns passing through D require the
   condition tested by COMMON to be true.

   When returning true, add all transitions like COMMON in D to WHERE.
   WHERE may contain a partial result on failure.  */

static bool
common_test_p (decision *d, transition *common, vec <transition *> *where)
{
  if (d->test.kind == rtx_test::ACCEPT)
    /* We found a successful return that didn't require COMMON.  */
    return false;
  if (d->test == common->from->test)
    {
      transition *trans = d->singleton ();
      if (!trans
	  || trans->optional != common->optional
	  || trans->labels != common->labels)
	return false;
      where->safe_push (trans);
      return true;
    }
  for (transition *trans = d->first; trans; trans = trans->next)
    for (decision *subd = trans->to->first; subd; subd = subd->next)
      if (!common_test_p (subd, common, where))
	return false;
  return true;
}

/* Indicates that we have tested GET_CODE (X) for a particular rtx X.  */
const unsigned char TESTED_CODE = 1;

/* Indicates that we have tested XVECLEN (X, 0) for a particular rtx X.  */
const unsigned char TESTED_VECLEN = 2;

/* Represents a set of conditions that are known to hold.  */
class known_conditions
{
public:
  /* A mask of TESTED_ values for each position, indexed by the position's
     id field.  */
  auto_vec <unsigned char> position_tests;

  /* Index N says whether operands[N] has been set.  */
  auto_vec <bool> set_operands;

  /* A guranteed lower bound on the value of peep2_current_count.  */
  int peep2_count;
};

/* Return true if TEST can safely be performed at D, where
   the conditions in KC hold.  TEST is known to occur along the
   first path from D (i.e. always following the first transition
   of the first decision).  Any intervening tests can be used as
   negative proof that hoisting isn't safe, but only KC can be used
   as positive proof.  */

static bool
safe_to_hoist_p (decision *d, const rtx_test &test, known_conditions *kc)
{
  switch (test.kind)
    {
    case rtx_test::C_TEST:
      /* In general, C tests require everything else to have been
	 verified and all operands to have been set up.  */
      return false;

    case rtx_test::ACCEPT:
      /* Don't accept something before all conditions have been tested.  */
      return false;

    case rtx_test::PREDICATE:
      /* Don't move a predicate over a test for VECLEN_GE, since the
	 predicate used in a match_parallel can legitimately expect the
	 length to be checked first.  */
      for (decision *subd = d;
	   subd->test != test;
	   subd = subd->first->to->first)
	if (subd->test.pos == test.pos
	    && subd->test.kind == rtx_test::VECLEN_GE)
	  return false;
      goto any_rtx;

    case rtx_test::DUPLICATE:
      /* Don't test for a match_dup until the associated operand has
	 been set.  */
      if (!kc->set_operands[test.u.opno])
	return false;
      goto any_rtx;

    case rtx_test::CODE:
    case rtx_test::MODE:
    case rtx_test::SAVED_CONST_INT:
    case rtx_test::SET_OP:
    any_rtx:
      /* Check whether it is safe to access the rtx under test.  */
      switch (test.pos->type)
	{
	case POS_PEEP2_INSN:
	  return test.pos->arg < kc->peep2_count;

	case POS_XEXP:
	  return kc->position_tests[test.pos->base->id] & TESTED_CODE;

	case POS_XVECEXP0:
	  return kc->position_tests[test.pos->base->id] & TESTED_VECLEN;
	}
      gcc_unreachable ();

    case rtx_test::REGNO_FIELD:
    case rtx_test::SUBREG_FIELD:
    case rtx_test::INT_FIELD:
    case rtx_test::WIDE_INT_FIELD:
    case rtx_test::VECLEN:
    case rtx_test::VECLEN_GE:
      /* These tests access a specific part of an rtx, so are only safe
	 once we know what the rtx is.  */
      return kc->position_tests[test.pos->id] & TESTED_CODE;

    case rtx_test::PEEP2_COUNT:
    case rtx_test::HAVE_NUM_CLOBBERS:
      /* These tests can be performed anywhere.  */
      return true;

    case rtx_test::PATTERN:
      gcc_unreachable ();
    }
  gcc_unreachable ();
}

/* Look for a transition that is taken by all successful returns from a range
   of decisions starting at OUTER and that would be better performed by
   OUTER's state instead.  On success, store all instances of that transition
   in WHERE and return the last decision in the range.  The range could
   just be OUTER, or it could include later decisions as well.

   WITH_POSITION_P is true if only tests with position POS should be tried,
   false if any test should be tried.  WORTHWHILE_SINGLE_P is true if the
   result is useful even when the range contains just a single decision
   with a single transition.  KC are the conditions that are known to
   hold at OUTER.  */

static decision *
find_common_test (decision *outer, bool with_position_p,
		  position *pos, bool worthwhile_single_p,
		  known_conditions *kc, vec <transition *> *where)
{
  /* After this, WORTHWHILE_SINGLE_P indicates whether a range that contains
     just a single decision is useful, regardless of the number of
     transitions it has.  */
  if (!outer->singleton ())
    worthwhile_single_p = true;
  /* Quick exit if we don't have enough decisions to form a worthwhile
     range.  */
  if (!worthwhile_single_p && !outer->next)
    return 0;
  /* Follow the first chain down, as one example of a path that needs
     to contain the common test.  */
  for (decision *d = outer; d; d = d->first->to->first)
    {
      transition *trans = d->singleton ();
      if (trans
	  && (!with_position_p || d->test.pos == pos)
	  && safe_to_hoist_p (outer, d->test, kc))
	{
	  if (common_test_p (outer, trans, where))
	    {
	      if (!outer->next)
		/* We checked above whether the move is worthwhile.  */
		return outer;
	      /* See how many decisions in OUTER's chain could reuse
		 the same test.  */
	      decision *outer_end = outer;
	      do
		{
		  unsigned int length = where->length ();
		  if (!common_test_p (outer_end->next, trans, where))
		    {
		      where->truncate (length);
		      break;
		    }
		  outer_end = outer_end->next;
		}
	      while (outer_end->next);
	      /* It is worth moving TRANS if it can be shared by more than
		 one decision.  */
	      if (outer_end != outer || worthwhile_single_p)
		return outer_end;
	    }
	  where->truncate (0);
	}
    }
  return 0;
}

/* Try to promote common subtests in S to a single, shared decision.
   Also try to bunch tests for the same position together.  POS is the
   position of the rtx tested before reaching S.  KC are the conditions
   that are known to hold on entry to S.  */

static void
cse_tests (position *pos, state *s, known_conditions *kc)
{
  for (decision *d = s->first; d; d = d->next)
    {
      auto_vec <transition *, 16> where;
      if (d->test.pos)
	{
	  /* Try to find conditions that don't depend on a particular rtx,
	     such as pnum_clobbers != NULL or peep2_current_count >= X.
	     It's usually better to check these conditions as soon as
	     possible, so the change is worthwhile even if there is
	     only one copy of the test.  */
	  decision *endd = find_common_test (d, true, 0, true, kc, &where);
	  if (!endd && d->test.pos != pos)
	    /* Try to find other conditions related to position POS
	       before moving to the new position.  Again, this is
	       worthwhile even if there is only one copy of the test,
	       since it means that fewer position variables are live
	       at a given time.  */
	    endd = find_common_test (d, true, pos, true, kc, &where);
	  if (!endd)
	    /* Try to find any condition that is used more than once.  */
	    endd = find_common_test (d, false, 0, false, kc, &where);
	  if (endd)
	    {
	      transition *common = where[0];
	      /* Replace [D, ENDD] with a test like COMMON.  We'll recurse
		 on the common test and see the original D again next time.  */
	      d = insert_decision_before (state::range (d, endd),
					  common->from->test,
					  common->labels,
					  common->optional);
	      /* Remove the old tests.  */
	      while (!where.is_empty ())
		{
		  transition *trans = where.pop ();
		  trans->from->s->replace (trans->from, trans->to->release ());
		}
	    }
	}

      /* Make sure that safe_to_hoist_p isn't being overly conservative.
	 It should realize that D's test is safe in the current
	 environment.  */
      gcc_assert (d->test.kind == rtx_test::C_TEST
		  || d->test.kind == rtx_test::ACCEPT
		  || safe_to_hoist_p (d, d->test, kc));

      /* D won't be changed any further by the current optimization.
	 Recurse with the state temporarily updated to include D.  */
      int prev = 0;
      switch (d->test.kind)
	{
	case rtx_test::CODE:
	  prev = kc->position_tests[d->test.pos->id];
	  kc->position_tests[d->test.pos->id] |= TESTED_CODE;
	  break;

	case rtx_test::VECLEN:
	case rtx_test::VECLEN_GE:
	  prev = kc->position_tests[d->test.pos->id];
	  kc->position_tests[d->test.pos->id] |= TESTED_VECLEN;
	  break;

	case rtx_test::SET_OP:
	  prev = kc->set_operands[d->test.u.opno];
	  gcc_assert (!prev);
	  kc->set_operands[d->test.u.opno] = true;
	  break;

	case rtx_test::PEEP2_COUNT:
	  prev = kc->peep2_count;
	  kc->peep2_count = MAX (prev, d->test.u.min_len);
	  break;

	default:
	  break;
	}
      for (transition *trans = d->first; trans; trans = trans->next)
	cse_tests (d->test.pos ? d->test.pos : pos, trans->to, kc);
      switch (d->test.kind)
	{
	case rtx_test::CODE:
	case rtx_test::VECLEN:
	case rtx_test::VECLEN_GE:
	  kc->position_tests[d->test.pos->id] = prev;
	  break;

	case rtx_test::SET_OP:
	  kc->set_operands[d->test.u.opno] = prev;
	  break;

	case rtx_test::PEEP2_COUNT:
	  kc->peep2_count = prev;
	  break;

	default:
	  break;
	}
    }
}

/* Return the type of value that can be used to parameterize test KIND,
   or parameter::UNSET if none.  */

parameter::type_enum
transition_parameter_type (rtx_test::kind_enum kind)
{
  switch (kind)
    {
    case rtx_test::CODE:
      return parameter::CODE;

    case rtx_test::MODE:
      return parameter::MODE;

    case rtx_test::REGNO_FIELD:
    case rtx_test::SUBREG_FIELD:
      return parameter::UINT;

    case rtx_test::INT_FIELD:
    case rtx_test::VECLEN:
    case rtx_test::PATTERN:
      return parameter::INT;

    case rtx_test::WIDE_INT_FIELD:
      return parameter::WIDE_INT;

    case rtx_test::PEEP2_COUNT:
    case rtx_test::VECLEN_GE:
    case rtx_test::SAVED_CONST_INT:
    case rtx_test::PREDICATE:
    case rtx_test::DUPLICATE:
    case rtx_test::HAVE_NUM_CLOBBERS:
    case rtx_test::C_TEST:
    case rtx_test::SET_OP:
    case rtx_test::ACCEPT:
      return parameter::UNSET;
    }
  gcc_unreachable ();
}

/* Initialize the pos_operand fields of each state reachable from S.
   If OPERAND_POS[ID] >= 0, the position with id ID is stored in
   operands[OPERAND_POS[ID]] on entry to S.  */

static void
find_operand_positions (state *s, vec <int> &operand_pos)
{
  for (decision *d = s->first; d; d = d->next)
    {
      int this_operand = (d->test.pos ? operand_pos[d->test.pos->id] : -1);
      if (this_operand >= 0)
	d->test.pos_operand = this_operand;
      if (d->test.kind == rtx_test::SET_OP)
	operand_pos[d->test.pos->id] = d->test.u.opno;
      for (transition *trans = d->first; trans; trans = trans->next)
	find_operand_positions (trans->to, operand_pos);
      if (d->test.kind == rtx_test::SET_OP)
	operand_pos[d->test.pos->id] = this_operand;
    }
}

/* Statistics about a matching routine.  */
class stats
{
public:
  stats ();

  /* The total number of decisions in the routine, excluding trivial
     ones that never fail.  */
  unsigned int num_decisions;

  /* The number of non-trivial decisions on the longest path through
     the routine, and the return value that contributes most to that
     long path.  */
  unsigned int longest_path;
  int longest_path_code;

  /* The maximum number of times that a single call to the routine
     can backtrack, and the value returned at the end of that path.
     "Backtracking" here means failing one decision in state and
     going onto to the next.  */
  unsigned int longest_backtrack;
  int longest_backtrack_code;
};

stats::stats ()
  : num_decisions (0), longest_path (0), longest_path_code (-1),
    longest_backtrack (0), longest_backtrack_code (-1) {}

/* Return statistics about S.  */

static stats
get_stats (state *s)
{
  stats for_s;
  unsigned int longest_path = 0;
  for (decision *d = s->first; d; d = d->next)
    {
      /* Work out the statistics for D.  */
      stats for_d;
      for (transition *trans = d->first; trans; trans = trans->next)
	{
	  stats for_trans = get_stats (trans->to);
	  for_d.num_decisions += for_trans.num_decisions;
	  /* Each transition is mutually-exclusive, so just pick the
	     longest of the individual paths.  */
	  if (for_d.longest_path <= for_trans.longest_path)
	    {
	      for_d.longest_path = for_trans.longest_path;
	      for_d.longest_path_code = for_trans.longest_path_code;
	    }
	  /* Likewise for backtracking.  */
	  if (for_d.longest_backtrack <= for_trans.longest_backtrack)
	    {
	      for_d.longest_backtrack = for_trans.longest_backtrack;
	      for_d.longest_backtrack_code = for_trans.longest_backtrack_code;
	    }
	}

      /* Account for D's test in its statistics.  */
      if (!d->test.single_outcome_p ())
	{
	  for_d.num_decisions += 1;
	  for_d.longest_path += 1;
	}
      if (d->test.kind == rtx_test::ACCEPT)
	{
	  for_d.longest_path_code = d->test.u.acceptance.u.full.code;
	  for_d.longest_backtrack_code = d->test.u.acceptance.u.full.code;
	}

      /* Keep a running count of the number of backtracks.  */
      if (d->prev)
	for_s.longest_backtrack += 1;

      /* Accumulate D's statistics into S's.  */
      for_s.num_decisions += for_d.num_decisions;
      for_s.longest_path += for_d.longest_path;
      for_s.longest_backtrack += for_d.longest_backtrack;

      /* Use the code from the decision with the longest individual path,
	 since that's more likely to be useful if trying to make the
	 path shorter.  In the event of a tie, pick the later decision,
	 since that's closer to the end of the path.  */
      if (longest_path <= for_d.longest_path)
	{
	  longest_path = for_d.longest_path;
	  for_s.longest_path_code = for_d.longest_path_code;
	}

      /* Later decisions in a state are necessarily in a longer backtrack
	 than earlier decisions.  */
      for_s.longest_backtrack_code = for_d.longest_backtrack_code;
    }
  return for_s;
}

/* Optimize ROOT.  Use TYPE to describe ROOT in status messages.  */

static void
optimize_subroutine_group (const char *type, state *root)
{
  /* Remove optional transitions that turned out not to be worthwhile.  */
  if (collapse_optional_decisions_p)
    collapse_optional_decisions (root);

  /* Try to remove duplicated tests and to rearrange tests into a more
     logical order.  */
  if (cse_tests_p)
    {
      known_conditions kc;
      kc.position_tests.safe_grow_cleared (num_positions, true);
      kc.set_operands.safe_grow_cleared (num_operands, true);
      kc.peep2_count = 1;
      cse_tests (&root_pos, root, &kc);
    }

  /* Try to simplify two or more tests into one.  */
  if (simplify_tests_p)
    simplify_tests (root);

  /* Try to use operands[] instead of xN variables.  */
  if (use_operand_variables_p)
    {
      auto_vec <int> operand_pos (num_positions);
      for (unsigned int i = 0; i < num_positions; ++i)
	operand_pos.quick_push (-1);
      find_operand_positions (root, operand_pos);
    }

  /* Print a summary of the new state.  */
  stats st = get_stats (root);
  fprintf (stderr, "Statistics for %s:\n", type);
  fprintf (stderr, "  Number of decisions: %6d\n", st.num_decisions);
  fprintf (stderr, "  longest path:        %6d (code: %6d)\n",
	   st.longest_path, st.longest_path_code);
  fprintf (stderr, "  longest backtrack:   %6d (code: %6d)\n",
	   st.longest_backtrack, st.longest_backtrack_code);
}

class merge_pattern_info;

/* Represents a transition from one pattern to another.  */
class merge_pattern_transition
{
public:
  merge_pattern_transition (merge_pattern_info *);

  /* The target pattern.  */
  merge_pattern_info *to;

  /* The parameters that the source pattern passes to the target pattern.
     "parameter (TYPE, true, I)" represents parameter I of the source
     pattern.  */
  auto_vec <parameter, MAX_PATTERN_PARAMS> params;
};

merge_pattern_transition::merge_pattern_transition (merge_pattern_info *to_in)
  : to (to_in)
{
}

/* Represents a pattern that can might match several states.  The pattern
   may replace parts of the test with a parameter value.  It may also
   replace transition labels with parameters.  */
class merge_pattern_info
{
public:
  merge_pattern_info (unsigned int);

  /* If PARAM_TEST_P, the state's singleton test should be generalized
     to use the runtime value of PARAMS[PARAM_TEST].  */
  unsigned int param_test : 8;

  /* If PARAM_TRANSITION_P, the state's single transition label should
     be replaced by the runtime value of PARAMS[PARAM_TRANSITION].  */
  unsigned int param_transition : 8;

  /* True if we have decided to generalize the root decision's test,
     as per PARAM_TEST.  */
  unsigned int param_test_p : 1;

  /* Likewise for the root decision's transition, as per PARAM_TRANSITION.  */
  unsigned int param_transition_p : 1;

  /* True if the contents of the structure are completely filled in.  */
  unsigned int complete_p : 1;

  /* The number of pseudo-statements in the pattern.  Used to decide
     whether it's big enough to break out into a subroutine.  */
  unsigned int num_statements;

  /* The number of states that use this pattern.  */
  unsigned int num_users;

  /* The number of distinct success values that the pattern returns.  */
  unsigned int num_results;

  /* This array has one element for each runtime parameter to the pattern.
     PARAMS[I] gives the default value of parameter I, which is always
     constant.

     These default parameters are used in cases where we match the
     pattern against some state S1, then add more parameters while
     matching against some state S2.  S1 is then left passing fewer
     parameters than S2.  The array gives us enough informatino to
     construct a full parameter list for S1 (see update_parameters).

     If we decide to create a subroutine for this pattern,
     PARAMS[I].type determines the C type of parameter I.  */
  auto_vec <parameter, MAX_PATTERN_PARAMS> params;

  /* All states that match this pattern must have the same number of
     transitions.  TRANSITIONS[I] describes the subpattern for transition
     number I; it is null if transition I represents a successful return
     from the pattern.  */
  auto_vec <merge_pattern_transition *, 1> transitions;

  /* The routine associated with the pattern, or null if we haven't generated
     one yet.  */
  pattern_routine *routine;
};

merge_pattern_info::merge_pattern_info (unsigned int num_transitions)
  : param_test (0),
    param_transition (0),
    param_test_p (false),
    param_transition_p (false),
    complete_p (false),
    num_statements (0),
    num_users (0),
    num_results (0),
    routine (0)
{
  transitions.safe_grow_cleared (num_transitions, true);
}

/* Describes one way of matching a particular state to a particular
   pattern.  */
class merge_state_result
{
public:
  merge_state_result (merge_pattern_info *, position *, merge_state_result *);

  /* A pattern that matches the state.  */
  merge_pattern_info *pattern;

  /* If we decide to use this match and create a subroutine for PATTERN,
     the state should pass the rtx at position ROOT to the pattern's
     rtx parameter.  A null root means that the pattern doesn't need
     an rtx parameter; all the rtxes it matches come from elsewhere.  */
  position *root;

  /* The parameters that should be passed to PATTERN for this state.
     If the array is shorter than PATTERN->params, the missing entries
     should be taken from the corresponding element of PATTERN->params.  */
  auto_vec <parameter, MAX_PATTERN_PARAMS> params;

  /* An earlier match for the same state, or null if none.  Patterns
     matched by earlier entries are smaller than PATTERN.  */
  merge_state_result *prev;
};

merge_state_result::merge_state_result (merge_pattern_info *pattern_in,
					position *root_in,
					merge_state_result *prev_in)
  : pattern (pattern_in), root (root_in), prev (prev_in)
{}

/* Information about a state, used while trying to match it against
   a pattern.  */
class merge_state_info
{
public:
  merge_state_info (state *);

  /* The state itself.  */
  state *s;

  /* Index I gives information about the target of transition I.  */
  merge_state_info *to_states;

  /* The number of transitions in S.  */
  unsigned int num_transitions;

  /* True if the state has been deleted in favor of a call to a
     pattern routine.  */
  bool merged_p;

  /* The previous state that might be a merge candidate for S, or null
     if no previous states could be merged with S.  */
  merge_state_info *prev_same_test;

  /* A list of pattern matches for this state.  */
  merge_state_result *res;
};

merge_state_info::merge_state_info (state *s_in)
  : s (s_in),
    to_states (0),
    num_transitions (0),
    merged_p (false),
    prev_same_test (0),
    res (0) {}

/* True if PAT would be useful as a subroutine.  */

static bool
useful_pattern_p (merge_pattern_info *pat)
{
  return pat->num_statements >= MIN_COMBINE_COST;
}

/* PAT2 is a subpattern of PAT1.  Return true if PAT2 should be inlined
   into PAT1's C routine.  */

static bool
same_pattern_p (merge_pattern_info *pat1, merge_pattern_info *pat2)
{
  return pat1->num_users == pat2->num_users || !useful_pattern_p (pat2);
}

/* PAT was previously matched against SINFO based on tentative matches
   for the target states of SINFO's state.  Return true if the match
   still holds; that is, if the target states of SINFO's state still
   match the corresponding transitions of PAT.  */

static bool
valid_result_p (merge_pattern_info *pat, merge_state_info *sinfo)
{
  for (unsigned int j = 0; j < sinfo->num_transitions; ++j)
    if (merge_pattern_transition *ptrans = pat->transitions[j])
      {
	merge_state_result *to_res = sinfo->to_states[j].res;
	if (!to_res || to_res->pattern != ptrans->to)
	  return false;
      }
  return true;
}

/* Remove any matches that are no longer valid from the head of SINFO's
   list of matches.  */

static void
prune_invalid_results (merge_state_info *sinfo)
{
  while (sinfo->res && !valid_result_p (sinfo->res->pattern, sinfo))
    {
      sinfo->res = sinfo->res->prev;
      gcc_assert (sinfo->res);
    }
}

/* Return true if PAT represents the biggest posssible match for SINFO;
   that is, if the next action of SINFO's state on return from PAT will
   be something that cannot be merged with any other state.  */

static bool
complete_result_p (merge_pattern_info *pat, merge_state_info *sinfo)
{
  for (unsigned int j = 0; j < sinfo->num_transitions; ++j)
    if (sinfo->to_states[j].res && !pat->transitions[j])
      return false;
  return true;
}

/* Update TO for any parameters that have been added to FROM since TO
   was last set.  The extra parameters in FROM will be constants or
   instructions to duplicate earlier parameters.  */

static void
update_parameters (vec <parameter> &to, const vec <parameter> &from)
{
  for (unsigned int i = to.length (); i < from.length (); ++i)
    to.quick_push (from[i]);
}

/* Return true if A and B can be tested by a single test.  If the test
   can be parameterised, store the parameter value for A in *PARAMA and
   the parameter value for B in *PARAMB, otherwise leave PARAMA and
   PARAMB alone.  */

static bool
compatible_tests_p (const rtx_test &a, const rtx_test &b,
		    parameter *parama, parameter *paramb)
{
  if (a.kind != b.kind)
    return false;
  switch (a.kind)
    {
    case rtx_test::PREDICATE:
      if (a.u.predicate.data != b.u.predicate.data)
	return false;
      *parama = parameter (parameter::MODE, false, a.u.predicate.mode);
      *paramb = parameter (parameter::MODE, false, b.u.predicate.mode);
      return true;

    case rtx_test::SAVED_CONST_INT:
      *parama = parameter (parameter::INT, false, a.u.integer.value);
      *paramb = parameter (parameter::INT, false, b.u.integer.value);
      return true;

    default:
      return a == b;
    }
}

/* PARAMS is an array of the parameters that a state is going to pass
   to a pattern routine.  It is still incomplete; index I has a kind of
   parameter::UNSET if we don't yet know what the state will pass
   as parameter I.  Try to make parameter ID equal VALUE, returning
   true on success.  */

static bool
set_parameter (vec <parameter> &params, unsigned int id,
	       const parameter &value)
{
  if (params[id].type == parameter::UNSET)
    {
      if (force_unique_params_p)
	for (unsigned int i = 0; i < params.length (); ++i)
	  if (params[i] == value)
	    return false;
      params[id] = value;
      return true;
    }
  return params[id] == value;
}

/* PARAMS2 is the "params" array for a pattern and PARAMS1 is the
   set of parameters that a particular state is going to pass to
   that pattern.

   Try to extend PARAMS1 and PARAMS2 so that there is a parameter
   that is equal to PARAM1 for the state and has a default value of
   PARAM2.  Parameters beginning at START were added as part of the
   same match and so may be reused.  */

static bool
add_parameter (vec <parameter> &params1, vec <parameter> &params2,
	       const parameter &param1, const parameter &param2,
	       unsigned int start, unsigned int *res)
{
  gcc_assert (params1.length () == params2.length ());
  gcc_assert (!param1.is_param && !param2.is_param);

  for (unsigned int i = start; i < params2.length (); ++i)
    if (params1[i] == param1 && params2[i] == param2)
      {
	*res = i;
	return true;
      }

  if (force_unique_params_p)
    for (unsigned int i = 0; i < params2.length (); ++i)
      if (params1[i] == param1 || params2[i] == param2)
	return false;

  if (params2.length () >= MAX_PATTERN_PARAMS)
    return false;

  *res = params2.length ();
  params1.quick_push (param1);
  params2.quick_push (param2);
  return true;
}

/* If *ROOTA is nonnull, return true if the same sequence of steps are
   required to reach A from *ROOTA as to reach B from ROOTB.  If *ROOTA
   is null, update it if necessary in order to make the condition hold.  */

static bool
merge_relative_positions (position **roota, position *a,
			  position *rootb, position *b)
{
  if (!relative_patterns_p)
    {
      if (a != b)
	return false;
      if (!*roota)
	{
	  *roota = rootb;
	  return true;
	}
      return *roota == rootb;
    }
  /* If B does not belong to the same instruction as ROOTB, we don't
     start with ROOTB but instead start with a call to peep2_next_insn.
     In that case the sequences for B and A are identical iff B and A
     are themselves identical.  */
  if (rootb->insn_id != b->insn_id)
    return a == b;
  while (rootb != b)
    {
      if (!a || b->type != a->type || b->arg != a->arg)
	return false;
      b = b->base;
      a = a->base;
    }
  if (!*roota)
    *roota = a;
  return *roota == a;
}

/* A hasher of states that treats two states as "equal" if they might be
   merged (but trying to be more discriminating than "return true").  */
struct test_pattern_hasher : nofree_ptr_hash <merge_state_info>
{
  static inline hashval_t hash (const value_type &);
  static inline bool equal (const value_type &, const compare_type &);
};

hashval_t
test_pattern_hasher::hash (merge_state_info *const &sinfo)
{
  inchash::hash h;
  decision *d = sinfo->s->singleton ();
  h.add_int (d->test.pos_operand + 1);
  if (!relative_patterns_p)
    h.add_int (d->test.pos ? d->test.pos->id + 1 : 0);
  h.add_int (d->test.kind);
  h.add_int (sinfo->num_transitions);
  return h.end ();
}

bool
test_pattern_hasher::equal (merge_state_info *const &sinfo1,
			    merge_state_info *const &sinfo2)
{
  decision *d1 = sinfo1->s->singleton ();
  decision *d2 = sinfo2->s->singleton ();
  gcc_assert (d1 && d2);

  parameter new_param1, new_param2;
  return (d1->test.pos_operand == d2->test.pos_operand
	  && (relative_patterns_p || d1->test.pos == d2->test.pos)
	  && compatible_tests_p (d1->test, d2->test, &new_param1, &new_param2)
	  && sinfo1->num_transitions == sinfo2->num_transitions);
}

/* Try to make the state described by SINFO1 use the same pattern as the
   state described by SINFO2.  Return true on success.

   SINFO1 and SINFO2 are known to have the same hash value.  */

static bool
merge_patterns (merge_state_info *sinfo1, merge_state_info *sinfo2)
{
  merge_state_result *res2 = sinfo2->res;
  merge_pattern_info *pat = res2->pattern;

  /* Write to temporary arrays while matching, in case we have to abort
     half way through.  */
  auto_vec <parameter, MAX_PATTERN_PARAMS> params1;
  auto_vec <parameter, MAX_PATTERN_PARAMS> params2;
  params1.quick_grow_cleared (pat->params.length ());
  params2.splice (pat->params);
  unsigned int start_param = params2.length ();

  /* An array for recording changes to PAT->transitions[?].params.
     All changes involve replacing a constant parameter with some
     PAT->params[N], where N is the second element of the pending_param.  */
  typedef std::pair <parameter *, unsigned int> pending_param;
  auto_vec <pending_param, 32> pending_params;

  decision *d1 = sinfo1->s->singleton ();
  decision *d2 = sinfo2->s->singleton ();
  gcc_assert (d1 && d2);

  /* If D2 tests a position, SINFO1's root relative to D1 is the same
     as SINFO2's root relative to D2.  */
  position *root1 = 0;
  position *root2 = res2->root;
  if (d2->test.pos_operand < 0
      && d1->test.pos
      && !merge_relative_positions (&root1, d1->test.pos,
				    root2, d2->test.pos))
    return false;

  /* Check whether the patterns have the same shape.  */
  unsigned int num_transitions = sinfo1->num_transitions;
  gcc_assert (num_transitions == sinfo2->num_transitions);
  for (unsigned int i = 0; i < num_transitions; ++i)
    if (merge_pattern_transition *ptrans = pat->transitions[i])
      {
	merge_state_result *to1_res = sinfo1->to_states[i].res;
	merge_state_result *to2_res = sinfo2->to_states[i].res;
	merge_pattern_info *to_pat = ptrans->to;
	gcc_assert (to2_res && to2_res->pattern == to_pat);
	if (!to1_res || to1_res->pattern != to_pat)
	  return false;
	if (to2_res->root
	    && !merge_relative_positions (&root1, to1_res->root,
					  root2, to2_res->root))
	  return false;
	/* Match the parameters that TO1_RES passes to TO_PAT with the
	   parameters that PAT passes to TO_PAT.  */
	update_parameters (to1_res->params, to_pat->params);
	for (unsigned int j = 0; j < to1_res->params.length (); ++j)
	  {
	    const parameter &param1 = to1_res->params[j];
	    const parameter &param2 = ptrans->params[j];
	    gcc_assert (!param1.is_param);
	    if (param2.is_param)
	      {
		if (!set_parameter (params1, param2.value, param1))
		  return false;
	      }
	    else if (param1 != param2)
	      {
		unsigned int id;
		if (!add_parameter (params1, params2,
				    param1, param2, start_param, &id))
		  return false;
		/* Record that PAT should now pass parameter ID to TO_PAT,
		   instead of the current contents of *PARAM2.  We only
		   make the change if the rest of the match succeeds.  */
		pending_params.safe_push
		  (pending_param (&ptrans->params[j], id));
	      }
	  }
      }

  unsigned int param_test = pat->param_test;
  unsigned int param_transition = pat->param_transition;
  bool param_test_p = pat->param_test_p;
  bool param_transition_p = pat->param_transition_p;

  /* If the tests don't match exactly, try to parameterize them.  */
  parameter new_param1, new_param2;
  if (!compatible_tests_p (d1->test, d2->test, &new_param1, &new_param2))
    gcc_unreachable ();
  if (new_param1.type != parameter::UNSET)
    {
      /* If the test has not already been parameterized, all existing
	 matches use constant NEW_PARAM2.  */
      if (param_test_p)
	{
	  if (!set_parameter (params1, param_test, new_param1))
	    return false;
	}
      else if (new_param1 != new_param2)
	{
	  if (!add_parameter (params1, params2, new_param1, new_param2,
			      start_param, &param_test))
	    return false;
	  param_test_p = true;
	}
    }

  /* Match the transitions.  */
  transition *trans1 = d1->first;
  transition *trans2 = d2->first;
  for (unsigned int i = 0; i < num_transitions; ++i)
    {
      if (param_transition_p || trans1->labels != trans2->labels)
	{
	  /* We can only generalize a single transition with a single
	     label.  */
	  if (num_transitions != 1
	      || trans1->labels.length () != 1
	      || trans2->labels.length () != 1)
	    return false;

	  /* Although we can match wide-int fields, in practice it leads
	     to some odd results for const_vectors.  We end up
	     parameterizing the first N const_ints of the vector
	     and then (once we reach the maximum number of parameters)
	     we go on to match the other elements exactly.  */
	  if (d1->test.kind == rtx_test::WIDE_INT_FIELD)
	    return false;

	  /* See whether the label has a generalizable type.  */
	  parameter::type_enum param_type
	    = transition_parameter_type (d1->test.kind);
	  if (param_type == parameter::UNSET)
	    return false;

	  /* Match the labels using parameters.  */
	  new_param1 = parameter (param_type, false, trans1->labels[0]);
	  if (param_transition_p)
	    {
	      if (!set_parameter (params1, param_transition, new_param1))
		return false;
	    }
	  else
	    {
	      new_param2 = parameter (param_type, false, trans2->labels[0]);
	      if (!add_parameter (params1, params2, new_param1, new_param2,
				  start_param, &param_transition))
		return false;
	      param_transition_p = true;
	    }
	}
      trans1 = trans1->next;
      trans2 = trans2->next;
    }

  /* Set any unset parameters to their default values.  This occurs if some
     other state needed something to be parameterized in order to match SINFO2,
     but SINFO1 on its own does not.  */
  for (unsigned int i = 0; i < params1.length (); ++i)
    if (params1[i].type == parameter::UNSET)
      params1[i] = params2[i];

  /* The match was successful.  Commit all pending changes to PAT.  */
  update_parameters (pat->params, params2);
  {
    pending_param *pp;
    unsigned int i;
    FOR_EACH_VEC_ELT (pending_params, i, pp)
      *pp->first = parameter (pp->first->type, true, pp->second);
  }
  pat->param_test = param_test;
  pat->param_transition = param_transition;
  pat->param_test_p = param_test_p;
  pat->param_transition_p = param_transition_p;

  /* Record the match of SINFO1.  */
  merge_state_result *new_res1 = new merge_state_result (pat, root1,
							 sinfo1->res);
  new_res1->params.splice (params1);
  sinfo1->res = new_res1;
  return true;
}

/* The number of states that were removed by calling pattern routines.  */
static unsigned int pattern_use_states;

/* The number of states used while defining pattern routines.  */
static unsigned int pattern_def_states;

/* Information used while constructing a use or definition of a pattern
   routine.  */
struct create_pattern_info
{
  /* The routine itself.  */
  pattern_routine *routine;

  /* The first unclaimed return value for this particular use or definition.
     We walk the substates of uses and definitions in the same order
     so each return value always refers to the same position within
     the pattern.  */
  unsigned int next_result;
};

static void populate_pattern_routine (create_pattern_info *,
				      merge_state_info *, state *,
				      const vec <parameter> &);

/* SINFO matches a pattern for which we've decided to create a C routine.
   Return a decision that performs a call to the pattern routine,
   but leave the caller to add the transitions to it.  Initialize CPI
   for this purpose.  Also create a definition for the pattern routine,
   if it doesn't already have one.

   PARAMS are the parameters that SINFO passes to its pattern.  */

static decision *
init_pattern_use (create_pattern_info *cpi, merge_state_info *sinfo,
		  const vec <parameter> &params)
{
  state *s = sinfo->s;
  merge_state_result *res = sinfo->res;
  merge_pattern_info *pat = res->pattern;
  cpi->routine = pat->routine;
  if (!cpi->routine)
    {
      /* We haven't defined the pattern routine yet, so create
	 a definition now.  */
      pattern_routine *routine = new pattern_routine;
      pat->routine = routine;
      cpi->routine = routine;
      routine->s = new state;
      routine->insn_p = false;
      routine->pnum_clobbers_p = false;

      /* Create an "idempotent" mapping of parameter I to parameter I.
	 Also record the C type of each parameter to the routine.  */
      auto_vec <parameter, MAX_PATTERN_PARAMS> def_params;
      for (unsigned int i = 0; i < pat->params.length (); ++i)
	{
	  def_params.quick_push (parameter (pat->params[i].type, true, i));
	  routine->param_types.quick_push (pat->params[i].type);
	}

      /* Any of the states that match the pattern could be used to
	 create the routine definition.  We might as well use SINFO
	 since it's already to hand.  This means that all positions
	 in the definition will be relative to RES->root.  */
      routine->pos = res->root;
      cpi->next_result = 0;
      populate_pattern_routine (cpi, sinfo, routine->s, def_params);
      gcc_assert (cpi->next_result == pat->num_results);

      /* Add the routine to the global list, after the subroutines
	 that it calls.  */
      routine->pattern_id = patterns.length ();
      patterns.safe_push (routine);
    }

  /* Create a decision to call the routine, passing PARAMS to it.  */
  pattern_use *use = new pattern_use;
  use->routine = pat->routine;
  use->params.splice (params);
  decision *d = new decision (rtx_test::pattern (res->root, use));

  /* If the original decision could use an element of operands[] instead
     of an rtx variable, try to transfer it to the new decision.  */
  if (s->first->test.pos && res->root == s->first->test.pos)
    d->test.pos_operand = s->first->test.pos_operand;

  cpi->next_result = 0;
  return d;
}

/* Make S return the next unclaimed pattern routine result for CPI.  */

static void
add_pattern_acceptance (create_pattern_info *cpi, state *s)
{
  acceptance_type acceptance;
  acceptance.type = SUBPATTERN;
  acceptance.partial_p = false;
  acceptance.u.full.code = cpi->next_result;
  add_decision (s, rtx_test::accept (acceptance), true, false);
  cpi->next_result += 1;
}

/* Initialize new empty state NEWS so that it implements SINFO's pattern
   (here referred to as "P").  P may be the top level of a pattern routine
   or a subpattern that should be inlined into its parent pattern's routine
   (as per same_pattern_p).  The choice of SINFO for a top-level pattern is
   arbitrary; it could be any of the states that use P.  The choice for
   subpatterns follows the choice for the parent pattern.

   PARAMS gives the value of each parameter to P in terms of the parameters
   to the top-level pattern.  If P itself is the top level pattern, PARAMS[I]
   is always "parameter (TYPE, true, I)".  */

static void
populate_pattern_routine (create_pattern_info *cpi, merge_state_info *sinfo,
			  state *news, const vec <parameter> &params)
{
  pattern_def_states += 1;

  decision *d = sinfo->s->singleton ();
  merge_pattern_info *pat = sinfo->res->pattern;
  pattern_routine *routine = cpi->routine;

  /* Create a copy of D's test for the pattern routine and generalize it
     as appropriate.  */
  decision *newd = new decision (d->test);
  gcc_assert (newd->test.pos_operand >= 0
	      || !newd->test.pos
	      || common_position (newd->test.pos,
				  routine->pos) == routine->pos);
  if (pat->param_test_p)
    {
      const parameter &param = params[pat->param_test];
      switch (newd->test.kind)
	{
	case rtx_test::PREDICATE:
	  newd->test.u.predicate.mode_is_param = param.is_param;
	  newd->test.u.predicate.mode = param.value;
	  break;

	case rtx_test::SAVED_CONST_INT:
	  newd->test.u.integer.is_param = param.is_param;
	  newd->test.u.integer.value = param.value;
	  break;

	default:
	  gcc_unreachable ();
	  break;
	}
    }
  if (d->test.kind == rtx_test::C_TEST)
    routine->insn_p = true;
  else if (d->test.kind == rtx_test::HAVE_NUM_CLOBBERS)
    routine->pnum_clobbers_p = true;
  news->push_back (newd);

  /* Fill in the transitions of NEWD.  */
  unsigned int i = 0;
  for (transition *trans = d->first; trans; trans = trans->next)
    {
      /* Create a new state to act as the target of the new transition.  */
      state *to_news = new state;
      if (merge_pattern_transition *ptrans = pat->transitions[i])
	{
	  /* The pattern hasn't finished matching yet.  Get the target
	     pattern and the corresponding target state of SINFO.  */
	  merge_pattern_info *to_pat = ptrans->to;
	  merge_state_info *to = sinfo->to_states + i;
	  gcc_assert (to->res->pattern == to_pat);
	  gcc_assert (ptrans->params.length () == to_pat->params.length ());

	  /* Express the parameters to TO_PAT in terms of the parameters
	     to the top-level pattern.  */
	  auto_vec <parameter, MAX_PATTERN_PARAMS> to_params;
	  for (unsigned int j = 0; j < ptrans->params.length (); ++j)
	    {
	      const parameter &param = ptrans->params[j];
	      to_params.quick_push (param.is_param
				    ? params[param.value]
				    : param);
	    }

	  if (same_pattern_p (pat, to_pat))
	    /* TO_PAT is part of the current routine, so just recurse.  */
	    populate_pattern_routine (cpi, to, to_news, to_params);
	  else
	    {
	      /* TO_PAT should be matched by calling a separate routine.  */
	      create_pattern_info sub_cpi;
	      decision *subd = init_pattern_use (&sub_cpi, to, to_params);
	      routine->insn_p |= sub_cpi.routine->insn_p;
	      routine->pnum_clobbers_p |= sub_cpi.routine->pnum_clobbers_p;

	      /* Add the pattern routine call to the new target state.  */
	      to_news->push_back (subd);

	      /* Add a transition for each successful call result.  */
	      for (unsigned int j = 0; j < to_pat->num_results; ++j)
		{
		  state *res = new state;
		  add_pattern_acceptance (cpi, res);
		  subd->push_back (new transition (j, res, false));
		}
	    }
	}
      else
	/* This transition corresponds to a successful match.  */
	add_pattern_acceptance (cpi, to_news);

      /* Create the transition itself, generalizing as necessary.  */
      transition *new_trans = new transition (trans->labels, to_news,
					      trans->optional);
      if (pat->param_transition_p)
	{
	  const parameter &param = params[pat->param_transition];
	  new_trans->is_param = param.is_param;
	  new_trans->labels[0] = param.value;
	}
      newd->push_back (new_trans);
      i += 1;
    }
}

/* USE is a decision that calls a pattern routine and SINFO is part of the
   original state tree that the call is supposed to replace.  Add the
   transitions for SINFO and its substates to USE.  */

static void
populate_pattern_use (create_pattern_info *cpi, decision *use,
		      merge_state_info *sinfo)
{
  pattern_use_states += 1;
  gcc_assert (!sinfo->merged_p);
  sinfo->merged_p = true;
  merge_state_result *res = sinfo->res;
  merge_pattern_info *pat = res->pattern;
  decision *d = sinfo->s->singleton ();
  unsigned int i = 0;
  for (transition *trans = d->first; trans; trans = trans->next)
    {
      if (pat->transitions[i])
	/* The target state is also part of the pattern.  */
	populate_pattern_use (cpi, use, sinfo->to_states + i);
      else
	{
	  /* The transition corresponds to a successful return from the
	     pattern routine.  */
	  use->push_back (new transition (cpi->next_result, trans->to, false));
	  cpi->next_result += 1;
	}
      i += 1;
    }
}

/* We have decided to replace SINFO's state with a call to a pattern
   routine.  Make the change, creating a definition of the pattern routine
   if it doesn't have one already.  */

static void
use_pattern (merge_state_info *sinfo)
{
  merge_state_result *res = sinfo->res;
  merge_pattern_info *pat = res->pattern;
  state *s = sinfo->s;

  /* The pattern may have acquired new parameters after it was matched
     against SINFO.  Update the parameters that SINFO passes accordingly.  */
  update_parameters (res->params, pat->params);

  create_pattern_info cpi;
  decision *d = init_pattern_use (&cpi, sinfo, res->params);
  populate_pattern_use (&cpi, d, sinfo);
  s->release ();
  s->push_back (d);
}

/* Look through the state trees in STATES for common patterns and
   split them into subroutines.  */

static void
split_out_patterns (vec <merge_state_info> &states)
{
  unsigned int first_transition = states.length ();
  hash_table <test_pattern_hasher> hashtab (128);
  /* Stage 1: Create an order in which parent states come before their child
     states and in which sibling states are at consecutive locations.
     Having consecutive sibling states allows merge_state_info to have
     a single to_states pointer.  */
  for (unsigned int i = 0; i < states.length (); ++i)
    for (decision *d = states[i].s->first; d; d = d->next)
      for (transition *trans = d->first; trans; trans = trans->next)
	{
	  states.safe_push (trans->to);
	  states[i].num_transitions += 1;
	}
  /* Stage 2: Now that the addresses are stable, set up the to_states
     pointers.  Look for states that might be merged and enter them
     into the hash table.  */
  for (unsigned int i = 0; i < states.length (); ++i)
    {
      merge_state_info *sinfo = &states[i];
      if (sinfo->num_transitions)
	{
	  sinfo->to_states = &states[first_transition];
	  first_transition += sinfo->num_transitions;
	}
      /* For simplicity, we only try to merge states that have a single
	 decision.  This is in any case the best we can do for peephole2,
	 since whether a peephole2 ACCEPT succeeds or not depends on the
	 specific peephole2 pattern (which is unique to each ACCEPT
	 and so couldn't be shared between states).  */
      if (decision *d = sinfo->s->singleton ())
	/* ACCEPT states are unique, so don't even try to merge them.  */
	if (d->test.kind != rtx_test::ACCEPT
	    && (pattern_have_num_clobbers_p
		|| d->test.kind != rtx_test::HAVE_NUM_CLOBBERS)
	    && (pattern_c_test_p
		|| d->test.kind != rtx_test::C_TEST))
	  {
	    merge_state_info **slot = hashtab.find_slot (sinfo, INSERT);
	    sinfo->prev_same_test = *slot;
	    *slot = sinfo;
	  }
    }
  /* Stage 3: Walk backwards through the list of states and try to merge
     them.  This is a greedy, bottom-up match; parent nodes can only start
     a new leaf pattern if they fail to match when combined with all child
     nodes that have matching patterns.

     For each state we keep a list of potential matches, with each
     potential match being larger (and deeper) than the next match in
     the list.  The final element in the list is a leaf pattern that
     matches just a single state.

     Each candidate pattern created in this loop is unique -- it won't
     have been seen by an earlier iteration.  We try to match each pattern
     with every state that appears earlier in STATES.

     Because the patterns created in the loop are unique, any state
     that already has a match must have a final potential match that
     is different from any new leaf pattern.  Therefore, when matching
     leaf patterns, we need only consider states whose list of matches
     is empty.

     The non-leaf patterns that we try are as deep as possible
     and are an extension of the state's previous best candidate match (PB).
     We need only consider states whose current potential match is also PB;
     any states that don't match as much as PB cannnot match the new pattern,
     while any states that already match more than PB must be different from
     the new pattern.  */
  for (unsigned int i2 = states.length (); i2-- > 0; )
    {
      merge_state_info *sinfo2 = &states[i2];

      /* Enforce the bottom-upness of the match: remove matches with later
	 states if SINFO2's child states ended up finding a better match.  */
      prune_invalid_results (sinfo2);

      /* Do nothing if the state doesn't match a later one and if there are
	 no earlier states it could match.  */
      if (!sinfo2->res && !sinfo2->prev_same_test)
	continue;

      merge_state_result *res2 = sinfo2->res;
      decision *d2 = sinfo2->s->singleton ();
      position *root2 = (d2->test.pos_operand < 0 ? d2->test.pos : 0);
      unsigned int num_transitions = sinfo2->num_transitions;

      /* If RES2 is null then SINFO2's test in isolation has not been seen
	 before.  First try matching that on its own.  */
      if (!res2)
	{
	  merge_pattern_info *new_pat
	    = new merge_pattern_info (num_transitions);
	  merge_state_result *new_res2
	    = new merge_state_result (new_pat, root2, res2);
	  sinfo2->res = new_res2;

	  new_pat->num_statements = !d2->test.single_outcome_p ();
	  new_pat->num_results = num_transitions;
	  bool matched_p = false;
	  /* Look for states that don't currently match anything but
	     can be made to match SINFO2 on its own.  */
	  for (merge_state_info *sinfo1 = sinfo2->prev_same_test; sinfo1;
	       sinfo1 = sinfo1->prev_same_test)
	    if (!sinfo1->res && merge_patterns (sinfo1, sinfo2))
	      matched_p = true;
	  if (!matched_p)
	    {
	      /* No other states match.  */
	      sinfo2->res = res2;
	      delete new_pat;
	      delete new_res2;
	      continue;
	    }
	  else
	    res2 = new_res2;
	}

      /* Keep the existing pattern if it's as good as anything we'd
	 create for SINFO2.  */
      if (complete_result_p (res2->pattern, sinfo2))
	{
	  res2->pattern->num_users += 1;
	  continue;
	}

      /* Create a new pattern for SINFO2.  */
      merge_pattern_info *new_pat = new merge_pattern_info (num_transitions);
      merge_state_result *new_res2
	= new merge_state_result (new_pat, root2, res2);
      sinfo2->res = new_res2;

      /* Fill in details about the pattern.  */
      new_pat->num_statements = !d2->test.single_outcome_p ();
      new_pat->num_results = 0;
      for (unsigned int j = 0; j < num_transitions; ++j)
	if (merge_state_result *to_res = sinfo2->to_states[j].res)
	  {
	    /* Count the target state as part of this pattern.
	       First update the root position so that it can reach
	       the target state's root.  */
	    if (to_res->root)
	      {
		if (new_res2->root)
		  new_res2->root = common_position (new_res2->root,
						    to_res->root);
		else
		  new_res2->root = to_res->root;
	      }
	    merge_pattern_info *to_pat = to_res->pattern;
	    merge_pattern_transition *ptrans
	      = new merge_pattern_transition (to_pat);

	    /* TO_PAT may have acquired more parameters when matching
	       states earlier in STATES than TO_RES's, but the list is
	       now final.  Make sure that TO_RES is up to date.  */
	    update_parameters (to_res->params, to_pat->params);

	    /* Start out by assuming that every user of NEW_PAT will
	       want to pass the same (constant) parameters as TO_RES.  */
	    update_parameters (ptrans->params, to_res->params);

	    new_pat->transitions[j] = ptrans;
	    new_pat->num_statements += to_pat->num_statements;
	    new_pat->num_results += to_pat->num_results;
	  }
	else
	  /* The target state doesn't match anything and so is not part
	     of the pattern.  */
	  new_pat->num_results += 1;

      /* See if any earlier states that match RES2's pattern also match
	 NEW_PAT.  */
      bool matched_p = false;
      for (merge_state_info *sinfo1 = sinfo2->prev_same_test; sinfo1;
	   sinfo1 = sinfo1->prev_same_test)
	{
	  prune_invalid_results (sinfo1);
	  if (sinfo1->res
	      && sinfo1->res->pattern == res2->pattern
	      && merge_patterns (sinfo1, sinfo2))
	    matched_p = true;
	}
      if (!matched_p)
	{
	  /* Nothing else matches NEW_PAT, so go back to the previous
	     pattern (possibly just a single-state one).  */
	  sinfo2->res = res2;
	  delete new_pat;
	  delete new_res2;
	}
      /* Assume that SINFO2 will use RES.  At this point we don't know
	 whether earlier states that match the same pattern will use
	 that match or a different one.  */
      sinfo2->res->pattern->num_users += 1;
    }
  /* Step 4: Finalize the choice of pattern for each state, ignoring
     patterns that were only used once.  Update each pattern's size
     so that it doesn't include subpatterns that are going to be split
     out into subroutines.  */
  for (unsigned int i = 0; i < states.length (); ++i)
    {
      merge_state_info *sinfo = &states[i];
      merge_state_result *res = sinfo->res;
      /* Wind past patterns that are only used by SINFO.  */
      while (res && res->pattern->num_users == 1)
	{
	  res = res->prev;
	  sinfo->res = res;
	  if (res)
	    res->pattern->num_users += 1;
	}
      if (!res)
	continue;

      /* We have a shared pattern and are now committed to the match.  */
      merge_pattern_info *pat = res->pattern;
      gcc_assert (valid_result_p (pat, sinfo));

      if (!pat->complete_p)
	{
	  /* Look for subpatterns that are going to be split out and remove
	     them from the number of statements.  */
	  for (unsigned int j = 0; j < sinfo->num_transitions; ++j)
	    if (merge_pattern_transition *ptrans = pat->transitions[j])
	      {
		merge_pattern_info *to_pat = ptrans->to;
		if (!same_pattern_p (pat, to_pat))
		  pat->num_statements -= to_pat->num_statements;
	      }
	  pat->complete_p = true;
	}
    }
  /* Step 5: Split out the patterns.  */
  for (unsigned int i = 0; i < states.length (); ++i)
    {
      merge_state_info *sinfo = &states[i];
      merge_state_result *res = sinfo->res;
      if (!sinfo->merged_p && res && useful_pattern_p (res->pattern))
	use_pattern (sinfo);
    }
  fprintf (stderr, "Shared %d out of %d states by creating %d new states,"
	   " saving %d\n",
	   pattern_use_states, states.length (), pattern_def_states,
	   pattern_use_states - pattern_def_states);
}

/* Information about a state tree that we're considering splitting into a
   subroutine.  */
struct state_size
{
  /* The number of pseudo-statements in the state tree.  */
  unsigned int num_statements;

  /* The approximate number of nested "if" and "switch" statements that
     would be required if control could fall through to a later state.  */
  unsigned int depth;
};

/* Pairs a transition with information about its target state.  */
typedef std::pair <transition *, state_size> subroutine_candidate;

/* Sort two subroutine_candidates so that the one with the largest
   number of statements comes last.  */

static int
subroutine_candidate_cmp (const void *a, const void *b)
{
  return int (((const subroutine_candidate *) a)->second.num_statements
	      - ((const subroutine_candidate *) b)->second.num_statements);
}

/* Turn S into a subroutine of type TYPE and add it to PROCS.  Return a new
   state that performs a subroutine call to S.  */

static state *
create_subroutine (routine_type type, state *s, vec <state *> &procs)
{
  procs.safe_push (s);
  acceptance_type acceptance;
  acceptance.type = type;
  acceptance.partial_p = true;
  acceptance.u.subroutine_id = procs.length ();
  state *news = new state;
  add_decision (news, rtx_test::accept (acceptance), true, false);
  return news;
}

/* Walk state tree S, of type TYPE, and look for subtrees that would be
   better split into subroutines.  Accumulate all such subroutines in PROCS.
   Return the size of the new state tree (excluding subroutines).  */

static state_size
find_subroutines (routine_type type, state *s, vec <state *> &procs)
{
  auto_vec <subroutine_candidate, 16> candidates;
  state_size size;
  size.num_statements = 0;
  size.depth = 0;
  for (decision *d = s->first; d; d = d->next)
    {
      if (!d->test.single_outcome_p ())
	size.num_statements += 1;
      for (transition *trans = d->first; trans; trans = trans->next)
	{
	  /* Keep chains of simple decisions together if we know that no
	     change of position is required.  We'll output this chain as a
	     single "if" statement, so it counts as a single nesting level.  */
	  if (d->test.pos && d->if_statement_p ())
	    for (;;)
	      {
		decision *newd = trans->to->singleton ();
		if (!newd
		    || (newd->test.pos
			&& newd->test.pos_operand < 0
			&& newd->test.pos != d->test.pos)
		    || !newd->if_statement_p ())
		  break;
		if (!newd->test.single_outcome_p ())
		  size.num_statements += 1;
		trans = newd->singleton ();
		if (newd->test.kind == rtx_test::SET_OP
		    || newd->test.kind == rtx_test::ACCEPT)
		  break;
	      }
	  /* The target of TRANS is a subroutine candidate.  First recurse
	     on it to see how big it is after subroutines have been
	     split out.  */
	  state_size to_size = find_subroutines (type, trans->to, procs);
	  if (d->next && to_size.depth > MAX_DEPTH)
	    /* Keeping the target state in the same routine would lead
	       to an excessive nesting of "if" and "switch" statements.
	       Split it out into a subroutine so that it can use
	       inverted tests that return early on failure.  */
	    trans->to = create_subroutine (type, trans->to, procs);
	  else
	    {
	      size.num_statements += to_size.num_statements;
	      if (to_size.num_statements < MIN_NUM_STATEMENTS)
		/* The target state is too small to be worth splitting.
		   Keep it in the same routine as S.  */
		size.depth = MAX (size.depth, to_size.depth);
	      else
		/* Assume for now that we'll keep the target state in the
		   same routine as S, but record it as a subroutine candidate
		   if S grows too big.  */
		candidates.safe_push (subroutine_candidate (trans, to_size));
	    }
	}
    }
  if (size.num_statements > MAX_NUM_STATEMENTS)
    {
      /* S is too big.  Sort the subroutine candidates so that bigger ones
	 are nearer the end.  */
      candidates.qsort (subroutine_candidate_cmp);
      while (!candidates.is_empty ()
	     && size.num_statements > MAX_NUM_STATEMENTS)
	{
	  /* Peel off a candidate and force it into a subroutine.  */
	  subroutine_candidate cand = candidates.pop ();
	  size.num_statements -= cand.second.num_statements;
	  cand.first->to = create_subroutine (type, cand.first->to, procs);
	}
    }
  /* Update the depth for subroutine candidates that we decided not to
     split out.  */
  for (unsigned int i = 0; i < candidates.length (); ++i)
    size.depth = MAX (size.depth, candidates[i].second.depth);
  size.depth += 1;
  return size;
}

/* Return true if, for all X, PRED (X, MODE) implies that X has mode MODE.  */

static bool
safe_predicate_mode (const struct pred_data *pred, machine_mode mode)
{
  /* Scalar integer constants have VOIDmode.  */
  if (GET_MODE_CLASS (mode) == MODE_INT
      && (pred->codes[CONST_INT]
	  || pred->codes[CONST_DOUBLE]
	  || pred->codes[CONST_WIDE_INT]
	  || pred->codes[LABEL_REF]))
    return false;

  return !pred->special && mode != VOIDmode;
}

/* Fill CODES with the set of codes that could be matched by PRED.  */

static void
get_predicate_codes (const struct pred_data *pred, int_set *codes)
{
  for (int i = 0; i < NUM_TRUE_RTX_CODE; ++i)
    if (!pred || pred->codes[i])
      codes->safe_push (i);
}

/* Return true if the first path through D1 tests the same thing as D2.  */

static bool
has_same_test_p (decision *d1, decision *d2)
{
  do
    {
      if (d1->test == d2->test)
        return true;
      d1 = d1->first->to->first;
    }
  while (d1);
  return false;
}

/* Return true if D1 and D2 cannot match the same rtx.  All states reachable
   from D2 have single decisions and all those decisions have single
   transitions.  */

static bool
mutually_exclusive_p (decision *d1, decision *d2)
{
  /* If one path through D1 fails to test the same thing as D2, assume
     that D2's test could be true for D1 and look for a later, more useful,
     test.  This isn't as expensive as it looks in practice.  */
  while (!has_same_test_p (d1, d2))
    {
      d2 = d2->singleton ()->to->singleton ();
      if (!d2)
	return false;
    }
  if (d1->test == d2->test)
    {
      /* Look for any transitions from D1 that have the same labels as
	 the transition from D2.  */
      transition *trans2 = d2->singleton ();
      for (transition *trans1 = d1->first; trans1; trans1 = trans1->next)
	{
	  int_set::iterator i1 = trans1->labels.begin ();
	  int_set::iterator end1 = trans1->labels.end ();
	  int_set::iterator i2 = trans2->labels.begin ();
	  int_set::iterator end2 = trans2->labels.end ();
	  while (i1 != end1 && i2 != end2)
	    if (*i1 < *i2)
	      ++i1;
	    else if (*i2 < *i1)
	      ++i2;
	    else
	      {
		/* TRANS1 has some labels in common with TRANS2.  Assume
		   that D1 and D2 could match the same rtx if the target
		   of TRANS1 could match the same rtx as D2.  */
		for (decision *subd1 = trans1->to->first;
		     subd1; subd1 = subd1->next)
		  if (!mutually_exclusive_p (subd1, d2))
		    return false;
		break;
	      }
	}
      return true;
    }
  for (transition *trans1 = d1->first; trans1; trans1 = trans1->next)
    for (decision *subd1 = trans1->to->first; subd1; subd1 = subd1->next)
      if (!mutually_exclusive_p (subd1, d2))
	return false;
  return true;
}

/* Try to merge S2's decision into D1, given that they have the same test.
   Fail only if EXCLUDE is nonnull and the new transition would have the
   same labels as *EXCLUDE.  When returning true, set *NEXT_S1, *NEXT_S2
   and *NEXT_EXCLUDE as for merge_into_state_1, or set *NEXT_S2 to null
   if the merge is complete.  */

static bool
merge_into_decision (decision *d1, state *s2, const int_set *exclude,
		     state **next_s1, state **next_s2,
		     const int_set **next_exclude)
{
  decision *d2 = s2->singleton ();
  transition *trans2 = d2->singleton ();

  /* Get a list of the transitions that intersect TRANS2.  */
  auto_vec <transition *, 32> intersecting;
  for (transition *trans1 = d1->first; trans1; trans1 = trans1->next)
    {
      int_set::iterator i1 = trans1->labels.begin ();
      int_set::iterator end1 = trans1->labels.end ();
      int_set::iterator i2 = trans2->labels.begin ();
      int_set::iterator end2 = trans2->labels.end ();
      bool trans1_is_subset = true;
      bool trans2_is_subset = true;
      bool intersect_p = false;
      while (i1 != end1 && i2 != end2)
	if (*i1 < *i2)
	  {
	    trans1_is_subset = false;
	    ++i1;
	  }
	else if (*i2 < *i1)
	  {
	    trans2_is_subset = false;
	    ++i2;
	  }
	else
	  {
	    intersect_p = true;
	    ++i1;
	    ++i2;
	  }
      if (i1 != end1)
	trans1_is_subset = false;
      if (i2 != end2)
	trans2_is_subset = false;
      if (trans1_is_subset && trans2_is_subset)
	{
	  /* There's already a transition that matches exactly.
	     Merge the target states.  */
	  trans1->optional &= trans2->optional;
	  *next_s1 = trans1->to;
	  *next_s2 = trans2->to;
	  *next_exclude = 0;
	  return true;
	}
      if (trans2_is_subset)
	{
	  /* TRANS1 has all the labels that TRANS2 needs.  Merge S2 into
	     the target of TRANS1, but (to avoid infinite recursion)
	     make sure that we don't end up creating another transition
	     like TRANS1.  */
	  *next_s1 = trans1->to;
	  *next_s2 = s2;
	  *next_exclude = &trans1->labels;
	  return true;
	}
      if (intersect_p)
	intersecting.safe_push (trans1);
    }

  if (intersecting.is_empty ())
    {
      /* No existing labels intersect the new ones.  We can just add
	 TRANS2 itself.  */
      d1->push_back (d2->release ());
      *next_s1 = 0;
      *next_s2 = 0;
      *next_exclude = 0;
      return true;
    }

  /* Take the union of the labels in INTERSECTING and TRANS2.  Store the
     result in COMBINED and use NEXT as a temporary.  */
  int_set tmp1 = trans2->labels, tmp2;
  int_set *combined = &tmp1, *next = &tmp2;
  for (unsigned int i = 0; i < intersecting.length (); ++i)
    {
      transition *trans1 = intersecting[i];
      next->truncate (0);
      next->safe_grow (trans1->labels.length () + combined->length (), true);
      int_set::iterator end
	= std::set_union (trans1->labels.begin (), trans1->labels.end (),
			  combined->begin (), combined->end (),
			  next->begin ());
      next->truncate (end - next->begin ());
      std::swap (next, combined);
    }

  /* Stop now if we've been told not to create a transition with these
     labels.  */
  if (exclude && *combined == *exclude)
    return false;

  /* Get the transition that should carry the new labels.  */
  transition *new_trans = intersecting[0];
  if (intersecting.length () == 1)
    {
      /* We're merging with one existing transition whose labels are a
	 subset of those required.  If both transitions are optional,
	 we can just expand the set of labels so that it's suitable
	 for both transitions.  It isn't worth preserving the original
	 transitions since we know that they can't be merged; we would
	 need to backtrack to S2 if TRANS1->to fails.  In contrast,
	 we might be able to merge the targets of the transitions
	 without any backtracking.

	 If instead the existing transition is not optional, ensure that
	 all target decisions are suitably protected.  Some decisions
	 might already have a more specific requirement than NEW_TRANS,
	 in which case there's no point testing NEW_TRANS as well.  E.g. this
	 would have happened if a test for an (eq ...) rtx had been
	 added to a decision that tested whether the code is suitable
	 for comparison_operator.  The original comparison_operator
	 transition would have been non-optional and the (eq ...) test
	 would be performed by a second decision in the target of that
	 transition.

	 The remaining case -- keeping the original optional transition
	 when adding a non-optional TRANS2 -- is a wash.  Preserving
	 the optional transition only helps if we later merge another
	 state S3 that is mutually exclusive with S2 and whose labels
	 belong to *COMBINED - TRANS1->labels.  We can then test the
	 original NEW_TRANS and S3 in the same decision.  We keep the
	 optional transition around for that case, but it occurs very
	 rarely.  */
      gcc_assert (new_trans->labels != *combined);
      if (!new_trans->optional || !trans2->optional)
	{
	  decision *start = 0;
	  for (decision *end = new_trans->to->first; end; end = end->next)
	    {
	      if (!start && end->test != d1->test)
		/* END belongs to a range of decisions that need to be
		   protected by NEW_TRANS.  */
		start = end;
	      if (start && (!end->next || end->next->test == d1->test))
		{
		  /* Protect [START, END] with NEW_TRANS.  The decisions
		     move to NEW_S and NEW_D becomes part of NEW_TRANS->to.  */
		  state *new_s = new state;
		  decision *new_d = new decision (d1->test);
		  new_d->push_back (new transition (new_trans->labels, new_s,
						    new_trans->optional));
		  state::range r (start, end);
		  new_trans->to->replace (r, new_d);
		  new_s->push_back (r);

		  /* Continue with an empty range.  */
		  start = 0;

		  /* Continue from the decision after NEW_D.  */
		  end = new_d;
		}
	    }
	}
      new_trans->optional = true;
      new_trans->labels = *combined;
    }
  else
    {
      /* We're merging more than one existing transition together.
	 Those transitions are successfully dividing the matching space
	 and so we want to preserve them, even if they're optional.

	 Create a new transition with the union set of labels and make
	 it go to a state that has the original transitions.  */
      decision *new_d = new decision (d1->test);
      for (unsigned int i = 0; i < intersecting.length (); ++i)
	new_d->push_back (d1->remove (intersecting[i]));

      state *new_s = new state;
      new_s->push_back (new_d);

      new_trans = new transition (*combined, new_s, true);
      d1->push_back (new_trans);
    }

  /* We now have an optional transition with labels *COMBINED.  Decide
     whether we can use it as TRANS2 or whether we need to merge S2
     into the target of NEW_TRANS.  */
  gcc_assert (new_trans->optional);
  if (new_trans->labels == trans2->labels)
    {
      /* NEW_TRANS matches TRANS2.  Just merge the target states.  */
      new_trans->optional = trans2->optional;
      *next_s1 = new_trans->to;
      *next_s2 = trans2->to;
      *next_exclude = 0;
    }
  else
    {
      /* Try to merge TRANS2 into the target of the overlapping transition,
	 but (to prevent infinite recursion or excessive redundancy) without
	 creating another transition of the same type.  */
      *next_s1 = new_trans->to;
      *next_s2 = s2;
      *next_exclude = &new_trans->labels;
    }
  return true;
}

/* Make progress in merging S2 into S1, given that each state in S2
   has a single decision.  If EXCLUDE is nonnull, avoid creating a new
   transition with the same test as S2's decision and with the labels
   in *EXCLUDE.

   Return true if there is still work to do.  When returning true,
   set *NEXT_S1, *NEXT_S2 and *NEXT_EXCLUDE to the values that
   S1, S2 and EXCLUDE should have next time round.

   If S1 and S2 both match a particular rtx, give priority to S1.  */

static bool
merge_into_state_1 (state *s1, state *s2, const int_set *exclude,
		    state **next_s1, state **next_s2,
		    const int_set **next_exclude)
{
  decision *d2 = s2->singleton ();
  if (decision *d1 = s1->last)
    {
      if (d1->test.terminal_p ())
	/* D1 is an unconditional return, so S2 can never match.  This can
	   sometimes be a bug in the .md description, but might also happen
	   if genconditions forces some conditions to true for certain
	   configurations.  */
	return false;

      /* Go backwards through the decisions in S1, stopping once we find one
	 that could match the same thing as S2.  */
      while (d1->prev && mutually_exclusive_p (d1, d2))
	d1 = d1->prev;

      /* Search forwards from that point, merging D2 into the first
	 decision we can.  */
      for (; d1; d1 = d1->next)
	{
	  /* If S2 performs some optional tests before testing the same thing
	     as D1, those tests do not help to distinguish D1 and S2, so it's
	     better to drop them.  Search through such optional decisions
	     until we find something that tests the same thing as D1.  */
	  state *sub_s2 = s2;
	  for (;;)
	    {
	      decision *sub_d2 = sub_s2->singleton ();
	      if (d1->test == sub_d2->test)
		{
		  /* Only apply EXCLUDE if we're testing the same thing
		     as D2.  */
		  const int_set *sub_exclude = (d2 == sub_d2 ? exclude : 0);

		  /* Try to merge SUB_S2 into D1.  This can only fail if
		     it would involve creating a new transition with
		     labels SUB_EXCLUDE.  */
		  if (merge_into_decision (d1, sub_s2, sub_exclude,
					   next_s1, next_s2, next_exclude))
		    return *next_s2 != 0;

		  /* Can't merge with D1; try a later decision.  */
		  break;
		}
	      transition *sub_trans2 = sub_d2->singleton ();
	      if (!sub_trans2->optional)
		/* Can't merge with D1; try a later decision.  */
		break;
	      sub_s2 = sub_trans2->to;
	    }
	}
    }

  /* We can't merge D2 with any existing decision.  Just add it to the end.  */
  s1->push_back (s2->release ());
  return false;
}

/* Merge S2 into S1.  If they both match a particular rtx, give
   priority to S1.  Each state in S2 has a single decision.  */

static void
merge_into_state (state *s1, state *s2)
{
  const int_set *exclude = 0;
  while (s2 && merge_into_state_1 (s1, s2, exclude, &s1, &s2, &exclude))
    continue;
}

/* Pairs a pattern that needs to be matched with the rtx position at
   which the pattern should occur.  */
class pattern_pos {
public:
  pattern_pos () {}
  pattern_pos (rtx, position *);

  rtx pattern;
  position *pos;
};

pattern_pos::pattern_pos (rtx pattern_in, position *pos_in)
  : pattern (pattern_in), pos (pos_in)
{}

/* Compare entries according to their depth-first order.  There shouldn't
   be two entries at the same position.  */

bool
operator < (const pattern_pos &e1, const pattern_pos &e2)
{
  int diff = compare_positions (e1.pos, e2.pos);
  gcc_assert (diff != 0 || e1.pattern == e2.pattern);
  return diff < 0;
}

/* Add new decisions to S that check whether the rtx at position POS
   matches PATTERN.  Return the state that is reached in that case.
   TOP_PATTERN is the overall pattern, as passed to match_pattern_1.  */

static state *
match_pattern_2 (state *s, md_rtx_info *info, position *pos, rtx pattern)
{
  auto_vec <pattern_pos, 32> worklist;
  auto_vec <pattern_pos, 32> pred_and_mode_tests;
  auto_vec <pattern_pos, 32> dup_tests;

  worklist.safe_push (pattern_pos (pattern, pos));
  while (!worklist.is_empty ())
    {
      pattern_pos next = worklist.pop ();
      pattern = next.pattern;
      pos = next.pos;
      unsigned int reverse_s = worklist.length ();

      enum rtx_code code = GET_CODE (pattern);
      switch (code)
	{
	case MATCH_OP_DUP:
	case MATCH_DUP:
	case MATCH_PAR_DUP:
	  /* Add a test that the rtx matches the earlier one, but only
	     after the structure and predicates have been checked.  */
	  dup_tests.safe_push (pattern_pos (pattern, pos));

	  /* Use the same code check as the original operand.  */
	  pattern = find_operand (info->def, XINT (pattern, 0), NULL_RTX);
	  /* Fall through.  */

	case MATCH_PARALLEL:
	case MATCH_OPERAND:
	case MATCH_SCRATCH:
	case MATCH_OPERATOR:
	  {
	    const char *pred_name = predicate_name (pattern);
	    const struct pred_data *pred = 0;
	    if (pred_name[0] != 0)
	      {
		pred = lookup_predicate (pred_name);
		/* Only report errors once per rtx.  */
		if (code == GET_CODE (pattern))
		  {
		    if (!pred)
		      error_at (info->loc, "unknown predicate '%s' used in %s",
				pred_name, GET_RTX_NAME (code));
		    else if (code == MATCH_PARALLEL
			     && pred->singleton != PARALLEL)
		      error_at (info->loc, "predicate '%s' used in"
				" match_parallel does not allow only PARALLEL",
				pred->name);
		  }
	      }

	    if (code == MATCH_PARALLEL || code == MATCH_PAR_DUP)
	      {
		/* Check that we have a parallel with enough elements.  */
		s = add_decision (s, rtx_test::code (pos), PARALLEL, false);
		int min_len = XVECLEN (pattern, 2);
		s = add_decision (s, rtx_test::veclen_ge (pos, min_len),
				  true, false);
	      }
	    else
	      {
		/* Check that the rtx has one of codes accepted by the
		   predicate.  This is necessary when matching suboperands
		   of a MATCH_OPERATOR or MATCH_OP_DUP, since we can't
		   call XEXP (X, N) without checking that X has at least
		   N+1 operands.  */
		int_set codes;
		get_predicate_codes (pred, &codes);
		bool need_codes = (pred
				   && (code == MATCH_OPERATOR
				       || code == MATCH_OP_DUP));
		s = add_decision (s, rtx_test::code (pos), codes, !need_codes);
	      }

	    /* Postpone the predicate check until we've checked the rest
	       of the rtx structure.  */
	    if (code == GET_CODE (pattern))
	      pred_and_mode_tests.safe_push (pattern_pos (pattern, pos));

	    /* If we need to match suboperands, add them to the worklist.  */
	    if (code == MATCH_OPERATOR || code == MATCH_PARALLEL)
	      {
		position **subpos_ptr;
		enum position_type pos_type;
		int i;
		if (code == MATCH_OPERATOR || code == MATCH_OP_DUP)
		  {
		    pos_type = POS_XEXP;
		    subpos_ptr = &pos->xexps;
		    i = (code == MATCH_OPERATOR ? 2 : 1);
		  }
		else
		  {
		    pos_type = POS_XVECEXP0;
		    subpos_ptr = &pos->xvecexp0s;
		    i = 2;
		  }
		for (int j = 0; j < XVECLEN (pattern, i); ++j)
		  {
		    position *subpos = next_position (subpos_ptr, pos,
						      pos_type, j);
		    worklist.safe_push (pattern_pos (XVECEXP (pattern, i, j),
					       subpos));
		    subpos_ptr = &subpos->next;
		  }
	      }
	    break;
	  }

	default:
	  {
	    /* Check that the rtx has the right code.  */
	    s = add_decision (s, rtx_test::code (pos), code, false);

	    /* Queue a test for the mode if one is specified.  */
	    if (GET_MODE (pattern) != VOIDmode)
	      pred_and_mode_tests.safe_push (pattern_pos (pattern, pos));

	    /* Push subrtxes onto the worklist.  Match nonrtx operands now.  */
	    const char *fmt = GET_RTX_FORMAT (code);
	    position **subpos_ptr = &pos->xexps;
	    for (size_t i = 0; fmt[i]; ++i)
	      {
		position *subpos = next_position (subpos_ptr, pos,
						  POS_XEXP, i);
		switch (fmt[i])
		  {
		  case 'e': case 'u':
		    worklist.safe_push (pattern_pos (XEXP (pattern, i),
						     subpos));
		    break;

		  case 'E':
		    {
		      /* Make sure the vector has the right number of
			 elements.  */
		      int length = XVECLEN (pattern, i);
		      s = add_decision (s, rtx_test::veclen (pos),
					length, false);

		      position **subpos2_ptr = &pos->xvecexp0s;
		      for (int j = 0; j < length; j++)
			{
			  position *subpos2 = next_position (subpos2_ptr, pos,
							     POS_XVECEXP0, j);
			  rtx x = XVECEXP (pattern, i, j);
			  worklist.safe_push (pattern_pos (x, subpos2));
			  subpos2_ptr = &subpos2->next;
			}
		      break;
		    }

		  case 'i':
		    /* Make sure that XINT (X, I) has the right value.  */
		    s = add_decision (s, rtx_test::int_field (pos, i),
				      XINT (pattern, i), false);
		    break;

		  case 'r':
		    /* Make sure that REGNO (X) has the right value.  */
		    gcc_assert (i == 0);
		    s = add_decision (s, rtx_test::regno_field (pos),
				      REGNO (pattern), false);
		    break;

		  case 'w':
		    /* Make sure that XWINT (X, I) has the right value.  */
		    s = add_decision (s, rtx_test::wide_int_field (pos, i),
				      XWINT (pattern, 0), false);
		    break;

		  case 'p':
		    /* We don't have a way of parsing polynomial offsets yet,
		       and hopefully never will.  */
		    s = add_decision (s, rtx_test::subreg_field (pos),
				      SUBREG_BYTE (pattern).to_constant (),
				      false);
		    break;

		  case '0':
		    break;

		  default:
		    gcc_unreachable ();
		  }
		subpos_ptr = &subpos->next;
	      }
	  }
	  break;
	}
      /* Operands are pushed onto the worklist so that later indices are
	 nearer the top.  That's what we want for SETs, since a SET_SRC
	 is a better discriminator than a SET_DEST.  In other cases it's
	 usually better to match earlier indices first.  This is especially
	 true of PARALLELs, where the first element tends to be the most
	 individual.  It's also true for commutative operators, where the
	 canonicalization rules say that the more complex operand should
	 come first.  */
      if (code != SET && worklist.length () > reverse_s)
	std::reverse (&worklist[0] + reverse_s,
		      &worklist[0] + worklist.length ());
    }

  /* Sort the predicate and mode tests so that they're in depth-first order.
     The main goal of this is to put SET_SRC match_operands after SET_DEST
     match_operands and after mode checks for the enclosing SET_SRC operators
     (such as the mode of a PLUS in an addition instruction).  The latter
     two types of test can determine the mode exactly, whereas a SET_SRC
     match_operand often has to cope with the possibility of the operand
     being a modeless constant integer.  E.g. something that matches
     register_operand (x, SImode) never matches register_operand (x, DImode),
     but a const_int that matches immediate_operand (x, SImode) also matches
     immediate_operand (x, DImode).  The register_operand cases can therefore
     be distinguished by a switch on the mode, but the immediate_operand
     cases can't.  */
  if (pred_and_mode_tests.length () > 1)
    std::sort (&pred_and_mode_tests[0],
	       &pred_and_mode_tests[0] + pred_and_mode_tests.length ());

  /* Add the mode and predicate tests.  */
  pattern_pos *e;
  unsigned int i;
  FOR_EACH_VEC_ELT (pred_and_mode_tests, i, e)
    {
      switch (GET_CODE (e->pattern))
	{
	case MATCH_PARALLEL:
	case MATCH_OPERAND:
	case MATCH_SCRATCH:
	case MATCH_OPERATOR:
	  {
	    int opno = XINT (e->pattern, 0);
	    num_operands = MAX (num_operands, opno + 1);
	    const char *pred_name = predicate_name (e->pattern);
	    if (pred_name[0])
	      {
		const struct pred_data *pred = lookup_predicate (pred_name);
		/* Check the mode first, to distinguish things like SImode
		   and DImode register_operands, as described above.  */
		machine_mode mode = GET_MODE (e->pattern);
		if (pred && safe_predicate_mode (pred, mode))
		  s = add_decision (s, rtx_test::mode (e->pos), mode, true);

		/* Assign to operands[] first, so that the rtx usually doesn't
		   need to be live across the call to the predicate.

		   This shouldn't cause a problem with dirtying the page,
		   since we fully expect to assign to operands[] at some point,
		   and since the caller usually writes to other parts of
		   recog_data anyway.  */
		s = add_decision (s, rtx_test::set_op (e->pos, opno),
				  true, false);
		s = add_decision (s, rtx_test::predicate (e->pos, pred, mode),
				  true, false);
	      }
	    else
	      /* Historically we've ignored the mode when there's no
		 predicate.  Just set up operands[] unconditionally.  */
	      s = add_decision (s, rtx_test::set_op (e->pos, opno),
				true, false);
	    break;
	  }

	default:
	  s = add_decision (s, rtx_test::mode (e->pos),
			    GET_MODE (e->pattern), false);
	  break;
	}
    }

  /* Finally add rtx_equal_p checks for duplicated operands.  */
  FOR_EACH_VEC_ELT (dup_tests, i, e)
    s = add_decision (s, rtx_test::duplicate (e->pos, XINT (e->pattern, 0)),
		      true, false);
  return s;
}

/* Add new decisions to S that make it return ACCEPTANCE if:

   (1) the rtx doesn't match anything already matched by S
   (2) the rtx matches TOP_PATTERN and
   (3) the C test required by INFO->def is true

   For peephole2, TOP_PATTERN is a SEQUENCE of the instruction patterns
   to match, otherwise it is a single instruction pattern.  */

static void
match_pattern_1 (state *s, md_rtx_info *info, rtx pattern,
		 acceptance_type acceptance)
{
  if (acceptance.type == PEEPHOLE2)
    {
      /* Match each individual instruction.  */
      position **subpos_ptr = &peep2_insn_pos_list;
      int count = 0;
      for (int i = 0; i < XVECLEN (pattern, 0); ++i)
	{
	  rtx x = XVECEXP (pattern, 0, i);
	  position *subpos = next_position (subpos_ptr, &root_pos,
					    POS_PEEP2_INSN, count);
	  if (count > 0)
	    s = add_decision (s, rtx_test::peep2_count (count + 1),
			      true, false);
	  s = match_pattern_2 (s, info, subpos, x);
	  subpos_ptr = &subpos->next;
	  count += 1;
	}
      acceptance.u.full.u.match_len = count - 1;
    }
  else
    {
      /* Make the rtx itself.  */
      s = match_pattern_2 (s, info, &root_pos, pattern);

      /* If the match is only valid when extra clobbers are added,
	 make sure we're able to pass that information to the caller.  */
      if (acceptance.type == RECOG && acceptance.u.full.u.num_clobbers)
	s = add_decision (s, rtx_test::have_num_clobbers (), true, false);
    }

  /* Make sure that the C test is true.  */
  const char *c_test = get_c_test (info->def);
  if (maybe_eval_c_test (c_test) != 1)
    s = add_decision (s, rtx_test::c_test (c_test), true, false);

  /* Accept the pattern.  */
  add_decision (s, rtx_test::accept (acceptance), true, false);
}

/* Like match_pattern_1, but (if merge_states_p) try to merge the
   decisions with what's already in S, to reduce the amount of
   backtracking.  */

static void
match_pattern (state *s, md_rtx_info *info, rtx pattern,
	       acceptance_type acceptance)
{
  if (merge_states_p)
    {
      state root;
      /* Add the decisions to a fresh state and then merge the full tree
	 into the existing one.  */
      match_pattern_1 (&root, info, pattern, acceptance);
      merge_into_state (s, &root);
    }
  else
    match_pattern_1 (s, info, pattern, acceptance);
}

/* Begin the output file.  */

static void
write_header (void)
{
  puts ("\
/* Generated automatically by the program `genrecog' from the target\n\
   machine description file.  */\n\
\n\
#define IN_TARGET_CODE 1\n\
\n\
#include \"config.h\"\n\
#include \"system.h\"\n\
#include \"coretypes.h\"\n\
#include \"backend.h\"\n\
#include \"predict.h\"\n\
#include \"rtl.h\"\n\
#include \"memmodel.h\"\n\
#include \"tm_p.h\"\n\
#include \"emit-rtl.h\"\n\
#include \"insn-config.h\"\n\
#include \"recog.h\"\n\
#include \"output.h\"\n\
#include \"flags.h\"\n\
#include \"df.h\"\n\
#include \"resource.h\"\n\
#include \"diagnostic-core.h\"\n\
#include \"reload.h\"\n\
#include \"regs.h\"\n\
#include \"tm-constrs.h\"\n\
\n");

  puts ("\n\
/* `recog' contains a decision tree that recognizes whether the rtx\n\
   X0 is a valid instruction.\n\
\n\
   recog returns -1 if the rtx is not valid.  If the rtx is valid, recog\n\
   returns a nonnegative number which is the insn code number for the\n\
   pattern that matched.  This is the same as the order in the machine\n\
   description of the entry that matched.  This number can be used as an\n\
   index into `insn_data' and other tables.\n");
  puts ("\
   The third parameter to recog is an optional pointer to an int.  If\n\
   present, recog will accept a pattern if it matches except for missing\n\
   CLOBBER expressions at the end.  In that case, the value pointed to by\n\
   the optional pointer will be set to the number of CLOBBERs that need\n\
   to be added (it should be initialized to zero by the caller).  If it");
  puts ("\
   is set nonzero, the caller should allocate a PARALLEL of the\n\
   appropriate size, copy the initial entries, and call add_clobbers\n\
   (found in insn-emit.c) to fill in the CLOBBERs.\n\
");

  puts ("\n\
   The function split_insns returns 0 if the rtl could not\n\
   be split or the split rtl as an INSN list if it can be.\n\
\n\
   The function peephole2_insns returns 0 if the rtl could not\n\
   be matched. If there was a match, the new rtl is returned in an INSN list,\n\
   and LAST_INSN will point to the last recognized insn in the old sequence.\n\
*/\n\n");
}

/* Return the C type of a parameter with type TYPE.  */

static const char *
parameter_type_string (parameter::type_enum type)
{
  switch (type)
    {
    case parameter::UNSET:
      break;

    case parameter::CODE:
      return "rtx_code";

    case parameter::MODE:
      return "machine_mode";

    case parameter::INT:
      return "int";

    case parameter::UINT:
      return "unsigned int";

    case parameter::WIDE_INT:
      return "HOST_WIDE_INT";
    }
  gcc_unreachable ();
}

/* Return true if ACCEPTANCE requires only a single C statement even in
   a backtracking context.  */

static bool
single_statement_p (const acceptance_type &acceptance)
{
  if (acceptance.partial_p)
    /* We need to handle failures of the subroutine.  */
    return false;
  switch (acceptance.type)
    {
    case SUBPATTERN:
    case SPLIT:
      return true;

    case RECOG:
      /* False if we need to assign to pnum_clobbers.  */
      return acceptance.u.full.u.num_clobbers == 0;

    case PEEPHOLE2:
      /* We need to assign to pmatch_len_ and handle null returns from the
	 peephole2 routine.  */
      return false;
    }
  gcc_unreachable ();
}

/* Return the C failure value for a routine of type TYPE.  */

static const char *
get_failure_return (routine_type type)
{
  switch (type)
    {
    case SUBPATTERN:
    case RECOG:
      return "-1";

    case SPLIT:
    case PEEPHOLE2:
      return "NULL";
    }
  gcc_unreachable ();
}

/* Indicates whether a block of code always returns or whether it can fall
   through.  */

enum exit_state {
  ES_RETURNED,
  ES_FALLTHROUGH
};

/* Information used while writing out code.  */

class output_state
{
public:
  /* The type of routine that we're generating.  */
  routine_type type;

  /* Maps position ids to xN variable numbers.  The entry is only valid if
     it is less than the length of VAR_TO_ID, but this holds for every position
     tested by a state when writing out that state.  */
  auto_vec <unsigned int> id_to_var;

  /* Maps xN variable numbers to position ids.  */
  auto_vec <unsigned int> var_to_id;

  /* Index N is true if variable xN has already been set.  */
  auto_vec <bool> seen_vars;
};

/* Return true if D is a call to a pattern routine and if there is some X
   such that the transition for pattern result N goes to a successful return
   with code X+N.  When returning true, set *BASE_OUT to this X and *COUNT_OUT
   to the number of return values.  (We know that every PATTERN decision has
   a transition for every successful return.)  */

static bool
terminal_pattern_p (decision *d, unsigned int *base_out,
		    unsigned int *count_out)
{
  if (d->test.kind != rtx_test::PATTERN)
    return false;
  unsigned int base = 0;
  unsigned int count = 0;
  for (transition *trans = d->first; trans; trans = trans->next)
    {
      if (trans->is_param || trans->labels.length () != 1)
	return false;
      decision *subd = trans->to->singleton ();
      if (!subd || subd->test.kind != rtx_test::ACCEPT)
	return false;
      unsigned int this_base = (subd->test.u.acceptance.u.full.code
				- trans->labels[0]);
      if (trans == d->first)
	base = this_base;
      else if (base != this_base)
	return false;
      count += 1;
    }
  *base_out = base;
  *count_out = count;
  return true;
}

/* Return true if TEST doesn't test an rtx or if the rtx it tests is
   already available in state OS.  */

static bool
test_position_available_p (output_state *os, const rtx_test &test)
{
  return (!test.pos
	  || test.pos_operand >= 0
	  || os->seen_vars[os->id_to_var[test.pos->id]]);
}

/* Like printf, but print INDENT spaces at the beginning.  */

static void ATTRIBUTE_PRINTF_2
printf_indent (unsigned int indent, const char *format, ...)
{
  va_list ap;
  va_start (ap, format);
  printf ("%*s", indent, "");
  vprintf (format, ap);
  va_end (ap);
}

/* Emit code to initialize the variable associated with POS, if it isn't
   already valid in state OS.  Indent each line by INDENT spaces.  Update
   OS with the new state.  */

static void
change_state (output_state *os, position *pos, unsigned int indent)
{
  unsigned int var = os->id_to_var[pos->id];
  gcc_assert (var < os->var_to_id.length () && os->var_to_id[var] == pos->id);
  if (os->seen_vars[var])
    return;
  switch (pos->type)
    {
    case POS_PEEP2_INSN:
      printf_indent (indent, "x%d = PATTERN (peep2_next_insn (%d));\n",
		     var, pos->arg);
      break;

    case POS_XEXP:
      change_state (os, pos->base, indent);
      printf_indent (indent, "x%d = XEXP (x%d, %d);\n",
		     var, os->id_to_var[pos->base->id], pos->arg);
      break;

    case POS_XVECEXP0:
      change_state (os, pos->base, indent);
      printf_indent (indent, "x%d = XVECEXP (x%d, 0, %d);\n",
		     var, os->id_to_var[pos->base->id], pos->arg);
      break;
    }
  os->seen_vars[var] = true;
}

/* Print the enumerator constant for CODE -- the upcase version of
   the name.  */

static void
print_code (enum rtx_code code)
{
  const char *p;
  for (p = GET_RTX_NAME (code); *p; p++)
    putchar (TOUPPER (*p));
}

/* Emit a uint64_t as an integer constant expression.  We need to take
   special care to avoid "decimal constant is so large that it is unsigned"
   warnings in the resulting code.  */

static void
print_host_wide_int (uint64_t val)
{
  uint64_t min = uint64_t (1) << (HOST_BITS_PER_WIDE_INT - 1);
  if (val == min)
    printf ("(" HOST_WIDE_INT_PRINT_DEC_C " - 1)", val + 1);
  else
    printf (HOST_WIDE_INT_PRINT_DEC_C, val);
}

/* Print the C expression for actual parameter PARAM.  */

static void
print_parameter_value (const parameter &param)
{
  if (param.is_param)
    printf ("i%d", (int) param.value + 1);
  else
    switch (param.type)
      {
      case parameter::UNSET:
	gcc_unreachable ();
	break;

      case parameter::CODE:
	print_code ((enum rtx_code) param.value);
	break;

      case parameter::MODE:
	printf ("E_%smode", GET_MODE_NAME ((machine_mode) param.value));
	break;

      case parameter::INT:
	printf ("%d", (int) param.value);
	break;

      case parameter::UINT:
	printf ("%u", (unsigned int) param.value);
	break;

      case parameter::WIDE_INT:
	print_host_wide_int (param.value);
	break;
      }
}

/* Print the C expression for the rtx tested by TEST.  */

static void
print_test_rtx (output_state *os, const rtx_test &test)
{
  if (test.pos_operand >= 0)
    printf ("operands[%d]", test.pos_operand);
  else
    printf ("x%d", os->id_to_var[test.pos->id]);
}

/* Print the C expression for non-boolean test TEST.  */

static void
print_nonbool_test (output_state *os, const rtx_test &test)
{
  switch (test.kind)
    {
    case rtx_test::CODE:
      printf ("GET_CODE (");
      print_test_rtx (os, test);
      printf (")");
      break;

    case rtx_test::MODE:
      printf ("GET_MODE (");
      print_test_rtx (os, test);
      printf (")");
      break;

    case rtx_test::VECLEN:
      printf ("XVECLEN (");
      print_test_rtx (os, test);
      printf (", 0)");
      break;

    case rtx_test::INT_FIELD:
      printf ("XINT (");
      print_test_rtx (os, test);
      printf (", %d)", test.u.opno);
      break;

    case rtx_test::REGNO_FIELD:
      printf ("REGNO (");
      print_test_rtx (os, test);
      printf (")");
      break;

    case rtx_test::SUBREG_FIELD:
      printf ("SUBREG_BYTE (");
      print_test_rtx (os, test);
      printf (")");
      break;

    case rtx_test::WIDE_INT_FIELD:
      printf ("XWINT (");
      print_test_rtx (os, test);
      printf (", %d)", test.u.opno);
      break;

    case rtx_test::PATTERN:
      {
	pattern_routine *routine = test.u.pattern->routine;
	printf ("pattern%d (", routine->pattern_id);
	const char *sep = "";
	if (test.pos)
	  {
	    print_test_rtx (os, test);
	    sep = ", ";
	  }
	if (routine->insn_p)
	  {
	    printf ("%sinsn", sep);
	    sep = ", ";
	  }
	if (routine->pnum_clobbers_p)
	  {
	    printf ("%spnum_clobbers", sep);
	    sep = ", ";
	  }
	for (unsigned int i = 0; i < test.u.pattern->params.length (); ++i)
	  {
	    fputs (sep, stdout);
	    print_parameter_value (test.u.pattern->params[i]);
	    sep = ", ";
	  }
	printf (")");
	break;
      }

    case rtx_test::PEEP2_COUNT:
    case rtx_test::VECLEN_GE:
    case rtx_test::SAVED_CONST_INT:
    case rtx_test::DUPLICATE:
    case rtx_test::PREDICATE:
    case rtx_test::SET_OP:
    case rtx_test::HAVE_NUM_CLOBBERS:
    case rtx_test::C_TEST:
    case rtx_test::ACCEPT:
      gcc_unreachable ();
    }
}

/* IS_PARAM and LABEL are taken from a transition whose source
   decision performs TEST.  Print the C code for the label.  */

static void
print_label_value (const rtx_test &test, bool is_param, uint64_t value)
{
  print_parameter_value (parameter (transition_parameter_type (test.kind),
				    is_param, value));
}

/* If IS_PARAM, print code to compare TEST with the C variable i<VALUE+1>.
   If !IS_PARAM, print code to compare TEST with the C constant VALUE.
   Test for inequality if INVERT_P, otherwise test for equality.  */

static void
print_test (output_state *os, const rtx_test &test, bool is_param,
	    uint64_t value, bool invert_p)
{
  switch (test.kind)
    {
      /* Handle the non-boolean TESTs.  */
    case rtx_test::CODE:
    case rtx_test::MODE:
    case rtx_test::VECLEN:
    case rtx_test::REGNO_FIELD:
    case rtx_test::INT_FIELD:
    case rtx_test::WIDE_INT_FIELD:
    case rtx_test::PATTERN:
      print_nonbool_test (os, test);
      printf (" %s ", invert_p ? "!=" : "==");
      print_label_value (test, is_param, value);
      break;

    case rtx_test::SUBREG_FIELD:
      printf ("%s (", invert_p ? "maybe_ne" : "known_eq");
      print_nonbool_test (os, test);
      printf (", ");
      print_label_value (test, is_param, value);
      printf (")");
      break;

    case rtx_test::SAVED_CONST_INT:
      gcc_assert (!is_param && value == 1);
      print_test_rtx (os, test);
      printf (" %s const_int_rtx[MAX_SAVED_CONST_INT + ",
	      invert_p ? "!=" : "==");
      print_parameter_value (parameter (parameter::INT,
					test.u.integer.is_param,
					test.u.integer.value));
      printf ("]");
      break;

    case rtx_test::PEEP2_COUNT:
      gcc_assert (!is_param && value == 1);
      printf ("peep2_current_count %s %d", invert_p ? "<" : ">=",
	      test.u.min_len);
      break;

    case rtx_test::VECLEN_GE:
      gcc_assert (!is_param && value == 1);
      printf ("XVECLEN (");
      print_test_rtx (os, test);
      printf (", 0) %s %d", invert_p ? "<" : ">=", test.u.min_len);
      break;

    case rtx_test::PREDICATE:
      gcc_assert (!is_param && value == 1);
      printf ("%s%s (", invert_p ? "!" : "", test.u.predicate.data->name);
      print_test_rtx (os, test);
      printf (", ");
      print_parameter_value (parameter (parameter::MODE,
					test.u.predicate.mode_is_param,
					test.u.predicate.mode));
      printf (")");
      break;

    case rtx_test::DUPLICATE:
      gcc_assert (!is_param && value == 1);
      printf ("%srtx_equal_p (", invert_p ? "!" : "");
      print_test_rtx (os, test);
      printf (", operands[%d])", test.u.opno);
      break;

    case rtx_test::HAVE_NUM_CLOBBERS:
      gcc_assert (!is_param && value == 1);
      printf ("pnum_clobbers %s NULL", invert_p ? "==" : "!=");
      break;

    case rtx_test::C_TEST:
      gcc_assert (!is_param && value == 1);
      if (invert_p)
	printf ("!");
      rtx_reader_ptr->print_c_condition (test.u.string);
      break;

    case rtx_test::ACCEPT:
    case rtx_test::SET_OP:
      gcc_unreachable ();
    }
}

static exit_state print_decision (output_state *, decision *,
				  unsigned int, bool);

/* Print code to perform S, indent each line by INDENT spaces.
   IS_FINAL is true if there are no fallback decisions to test on failure;
   if the state fails then the entire routine fails.  */

static exit_state
print_state (output_state *os, state *s, unsigned int indent, bool is_final)
{
  exit_state es = ES_FALLTHROUGH;
  for (decision *d = s->first; d; d = d->next)
    es = print_decision (os, d, indent, is_final && !d->next);
  if (es != ES_RETURNED && is_final)
    {
      printf_indent (indent, "return %s;\n", get_failure_return (os->type));
      es = ES_RETURNED;
    }
  return es;
}

/* Print the code for subroutine call ACCEPTANCE (for which partial_p
   is known to be true).  Return the C condition that indicates a successful
   match.  */

static const char *
print_subroutine_call (const acceptance_type &acceptance)
{
  switch (acceptance.type)
    {
    case SUBPATTERN:
      gcc_unreachable ();

    case RECOG:
      printf ("recog_%d (x1, insn, pnum_clobbers)",
	      acceptance.u.subroutine_id);
      return ">= 0";

    case SPLIT:
      printf ("split_%d (x1, insn)", acceptance.u.subroutine_id);
      return "!= NULL_RTX";

    case PEEPHOLE2:
      printf ("peephole2_%d (x1, insn, pmatch_len_)",
	      acceptance.u.subroutine_id);
      return "!= NULL_RTX";
    }
  gcc_unreachable ();
}

/* Print code for the successful match described by ACCEPTANCE.
   INDENT and IS_FINAL are as for print_state.  */

static exit_state
print_acceptance (const acceptance_type &acceptance, unsigned int indent,
		  bool is_final)
{
  if (acceptance.partial_p)
    {
      /* Defer the rest of the match to a subroutine.  */
      if (is_final)
	{
	  printf_indent (indent, "return ");
	  print_subroutine_call (acceptance);
	  printf (";\n");
	  return ES_RETURNED;
	}
      else
	{
	  printf_indent (indent, "res = ");
	  const char *res_test = print_subroutine_call (acceptance);
	  printf (";\n");
	  printf_indent (indent, "if (res %s)\n", res_test);
	  printf_indent (indent + 2, "return res;\n");
	  return ES_FALLTHROUGH;
	}
    }
  switch (acceptance.type)
    {
    case SUBPATTERN:
      printf_indent (indent, "return %d;\n", acceptance.u.full.code);
      return ES_RETURNED;

    case RECOG:
      if (acceptance.u.full.u.num_clobbers != 0)
	printf_indent (indent, "*pnum_clobbers = %d;\n",
		       acceptance.u.full.u.num_clobbers);
      printf_indent (indent, "return %d; /* %s */\n", acceptance.u.full.code,
		     get_insn_name (acceptance.u.full.code));
      return ES_RETURNED;

    case SPLIT:
      printf_indent (indent, "return gen_split_%d (insn, operands);\n",
		     acceptance.u.full.code);
      return ES_RETURNED;

    case PEEPHOLE2:
      printf_indent (indent, "*pmatch_len_ = %d;\n",
		     acceptance.u.full.u.match_len);
      if (is_final)
	{
	  printf_indent (indent, "return gen_peephole2_%d (insn, operands);\n",
			 acceptance.u.full.code);
	  return ES_RETURNED;
	}
      else
	{
	  printf_indent (indent, "res = gen_peephole2_%d (insn, operands);\n",
			 acceptance.u.full.code);
	  printf_indent (indent, "if (res != NULL_RTX)\n");
	  printf_indent (indent + 2, "return res;\n");
	  return ES_FALLTHROUGH;
	}
    }
  gcc_unreachable ();
}

/* Print code to perform D.  INDENT and IS_FINAL are as for print_state.  */

static exit_state
print_decision (output_state *os, decision *d, unsigned int indent,
		bool is_final)
{
  uint64_t label;
  unsigned int base, count;

  /* Make sure the rtx under test is available either in operands[] or
     in an xN variable.  */
  if (d->test.pos && d->test.pos_operand < 0)
    change_state (os, d->test.pos, indent);

  /* Look for cases where a pattern routine P1 calls another pattern routine
     P2 and where P1 returns X + BASE whenever P2 returns X.  If IS_FINAL
     is true and BASE is zero we can simply use:

        return patternN (...);

     Otherwise we can use:

        res = patternN (...);
	if (res >= 0)
	  return res + BASE;

     However, if BASE is nonzero and patternN only returns 0 or -1,
     the usual "return BASE;" is better than "return res + BASE;".
     If BASE is zero, "return res;" should be better than "return 0;",
     since no assignment to the return register is required.  */
  if (os->type == SUBPATTERN
      && terminal_pattern_p (d, &base, &count)
      && (base == 0 || count > 1))
    {
      if (is_final && base == 0)
	{
	  printf_indent (indent, "return ");
	  print_nonbool_test (os, d->test);
	  printf ("; /* [-1, %d] */\n", count - 1);
	  return ES_RETURNED;
	}
      else
	{
	  printf_indent (indent, "res = ");
	  print_nonbool_test (os, d->test);
	  printf (";\n");
	  printf_indent (indent, "if (res >= 0)\n");
	  printf_indent (indent + 2, "return res");
	  if (base != 0)
	    printf (" + %d", base);
	  printf ("; /* [%d, %d] */\n", base, base + count - 1);
	  return ES_FALLTHROUGH;
	}
    }
  else if (d->test.kind == rtx_test::ACCEPT)
    return print_acceptance (d->test.u.acceptance, indent, is_final);
  else if (d->test.kind == rtx_test::SET_OP)
    {
      printf_indent (indent, "operands[%d] = ", d->test.u.opno);
      print_test_rtx (os, d->test);
      printf (";\n");
      return print_state (os, d->singleton ()->to, indent, is_final);
    }
  /* Handle decisions with a single transition and a single transition
     label.  */
  else if (d->if_statement_p (&label))
    {
      transition *trans = d->singleton ();
      if (mark_optional_transitions_p && trans->optional)
	printf_indent (indent, "/* OPTIONAL IF */\n");

      /* Print the condition associated with TRANS.  Invert it if IS_FINAL,
	 so that we return immediately on failure and fall through on
	 success.  */
      printf_indent (indent, "if (");
      print_test (os, d->test, trans->is_param, label, is_final);

      /* Look for following states that would be handled by this code
	 on recursion.  If they don't need any preparatory statements,
	 include them in the current "if" statement rather than creating
	 a new one.  */
      for (;;)
	{
	  d = trans->to->singleton ();
	  if (!d
	      || d->test.kind == rtx_test::ACCEPT
	      || d->test.kind == rtx_test::SET_OP
	      || !d->if_statement_p (&label)
	      || !test_position_available_p (os, d->test))
	    break;
	  trans = d->first;
	  printf ("\n");
	  if (mark_optional_transitions_p && trans->optional)
	    printf_indent (indent + 4, "/* OPTIONAL IF */\n");
	  printf_indent (indent + 4, "%s ", is_final ? "||" : "&&");
	  print_test (os, d->test, trans->is_param, label, is_final);
	}
      printf (")\n");

      /* Print the conditional code with INDENT + 2 and the fallthrough
	 code with indent INDENT.  */
      state *to = trans->to;
      if (is_final)
	{
	  /* We inverted the condition above, so return failure in the
	     "if" body and fall through to the target of the transition.  */
	  printf_indent (indent + 2, "return %s;\n",
			 get_failure_return (os->type));
	  return print_state (os, to, indent, is_final);
	}
      else if (to->singleton ()
	       && to->first->test.kind == rtx_test::ACCEPT
	       && single_statement_p (to->first->test.u.acceptance))
	{
	  /* The target of the transition is a simple "return" statement.
	     It doesn't need any braces and doesn't fall through.  */
	  if (print_acceptance (to->first->test.u.acceptance,
				indent + 2, true) != ES_RETURNED)
	    gcc_unreachable ();
	  return ES_FALLTHROUGH;
	}
      else
	{
	  /* The general case.  Output code for the target of the transition
	     in braces.  This will not invalidate any of the xN variables
	     that are already valid, but we mustn't rely on any that are
	     set by the "if" body.  */
	  auto_vec <bool, 32> old_seen;
	  old_seen.safe_splice (os->seen_vars);

	  printf_indent (indent + 2, "{\n");
	  print_state (os, trans->to, indent + 4, is_final);
	  printf_indent (indent + 2, "}\n");

	  os->seen_vars.truncate (0);
	  os->seen_vars.splice (old_seen);
	  return ES_FALLTHROUGH;
	}
    }
  else
    {
      /* Output the decision as a switch statement.  */
      printf_indent (indent, "switch (");
      print_nonbool_test (os, d->test);
      printf (")\n");

      /* Each case statement starts with the same set of valid variables.
	 These are also the only variables will be valid on fallthrough.  */
      auto_vec <bool, 32> old_seen;
      old_seen.safe_splice (os->seen_vars);

      printf_indent (indent + 2, "{\n");
      for (transition *trans = d->first; trans; trans = trans->next)
	{
	  gcc_assert (!trans->is_param);
	  if (mark_optional_transitions_p && trans->optional)
	    printf_indent (indent + 2, "/* OPTIONAL CASE */\n");
	  for (int_set::iterator j = trans->labels.begin ();
	       j != trans->labels.end (); ++j)
	    {
	      printf_indent (indent + 2, "case ");
	      print_label_value (d->test, trans->is_param, *j);
	      printf (":\n");
	    }
	  if (print_state (os, trans->to, indent + 4, is_final))
	    {
	      /* The state can fall through.  Add an explicit break.  */
	      gcc_assert (!is_final);
	      printf_indent (indent + 4, "break;\n");
	    }
	  printf ("\n");

	  /* Restore the original set of valid variables.  */
	  os->seen_vars.truncate (0);
	  os->seen_vars.splice (old_seen);
	}
      /* Add a default case.  */
      printf_indent (indent + 2, "default:\n");
      if (is_final)
	printf_indent (indent + 4, "return %s;\n",
		       get_failure_return (os->type));
      else
	printf_indent (indent + 4, "break;\n");
      printf_indent (indent + 2, "}\n");
      return is_final ? ES_RETURNED : ES_FALLTHROUGH;
    }
}

/* Make sure that OS has a position variable for POS.  ROOT_P is true if
   POS is the root position for the routine.  */

static void
assign_position_var (output_state *os, position *pos, bool root_p)
{
  unsigned int idx = os->id_to_var[pos->id];
  if (idx < os->var_to_id.length () && os->var_to_id[idx] == pos->id)
    return;
  if (!root_p && pos->type != POS_PEEP2_INSN)
    assign_position_var (os, pos->base, false);
  os->id_to_var[pos->id] = os->var_to_id.length ();
  os->var_to_id.safe_push (pos->id);
}

/* Make sure that OS has the position variables required by S.  */

static void
assign_position_vars (output_state *os, state *s)
{
  for (decision *d = s->first; d; d = d->next)
    {
      /* Positions associated with operands can be read from the
	 operands[] array.  */
      if (d->test.pos && d->test.pos_operand < 0)
	assign_position_var (os, d->test.pos, false);
      for (transition *trans = d->first; trans; trans = trans->next)
	assign_position_vars (os, trans->to);
    }
}

/* Print the open brace and variable definitions for a routine that
   implements S.  ROOT is the deepest rtx from which S can access all
   relevant parts of the first instruction it matches.  Initialize OS
   so that every relevant position has an rtx variable xN and so that
   only ROOT's variable has a valid value.  */

static void
print_subroutine_start (output_state *os, state *s, position *root)
{
  printf ("{\n  rtx * const operands ATTRIBUTE_UNUSED"
	  " = &recog_data.operand[0];\n");
  os->var_to_id.truncate (0);
  os->seen_vars.truncate (0);
  if (root)
    {
      /* Create a fake entry for position 0 so that an id_to_var of 0
	 is always invalid.  This also makes the xN variables naturally
	 1-based rather than 0-based.  */
      os->var_to_id.safe_push (num_positions);

      /* Associate ROOT with x1.  */
      assign_position_var (os, root, true);

      /* Assign xN variables to all other relevant positions.  */
      assign_position_vars (os, s);

      /* Output the variable declarations (except for ROOT's, which is
	 passed in as a parameter).  */
      unsigned int num_vars = os->var_to_id.length ();
      if (num_vars > 2)
	{
	  for (unsigned int i = 2; i < num_vars; ++i)
	    /* Print 8 rtx variables to a line.  */
	    printf ("%s x%d",
		    i == 2 ? "  rtx" : (i - 2) % 8 == 0 ? ";\n  rtx" : ",", i);
	  printf (";\n");
	}

      /* Say that x1 is valid and the rest aren't.  */
      os->seen_vars.safe_grow_cleared (num_vars, true);
      os->seen_vars[1] = true;
    }
  if (os->type == SUBPATTERN || os->type == RECOG)
    printf ("  int res ATTRIBUTE_UNUSED;\n");
  else
    printf ("  rtx_insn *res ATTRIBUTE_UNUSED;\n");
}

/* Output the definition of pattern routine ROUTINE.  */

static void
print_pattern (output_state *os, pattern_routine *routine)
{
  printf ("\nstatic int\npattern%d (", routine->pattern_id);
  const char *sep = "";
  /* Add the top-level rtx parameter, if any.  */
  if (routine->pos)
    {
      printf ("%srtx x1", sep);
      sep = ", ";
    }
  /* Add the optional parameters.  */
  if (routine->insn_p)
    {
      /* We can't easily tell whether a C condition actually reads INSN,
	 so add an ATTRIBUTE_UNUSED just in case.  */
      printf ("%srtx_insn *insn ATTRIBUTE_UNUSED", sep);
      sep = ", ";
    }
  if (routine->pnum_clobbers_p)
    {
      printf ("%sint *pnum_clobbers", sep);
      sep = ", ";
    }
  /* Add the "i" parameters.  */
  for (unsigned int i = 0; i < routine->param_types.length (); ++i)
    {
      printf ("%s%s i%d", sep,
	      parameter_type_string (routine->param_types[i]), i + 1);
      sep = ", ";
    }
  printf (")\n");
  os->type = SUBPATTERN;
  print_subroutine_start (os, routine->s, routine->pos);
  print_state (os, routine->s, 2, true);
  printf ("}\n");
}

/* Output a routine of type TYPE that implements S.  PROC_ID is the
   number of the subroutine associated with S, or 0 if S is the main
   routine.  */

static void
print_subroutine (output_state *os, state *s, int proc_id)
{
  printf ("\n");
  switch (os->type)
    {
    case SUBPATTERN:
      gcc_unreachable ();

    case RECOG:
      if (proc_id)
	printf ("static int\nrecog_%d", proc_id);
      else
	printf ("int\nrecog");
      printf (" (rtx x1 ATTRIBUTE_UNUSED,\n"
	      "\trtx_insn *insn ATTRIBUTE_UNUSED,\n"
	      "\tint *pnum_clobbers ATTRIBUTE_UNUSED)\n");
      break;

    case SPLIT:
      if (proc_id)
	printf ("static rtx_insn *\nsplit_%d", proc_id);
      else
	printf ("rtx_insn *\nsplit_insns");
      printf (" (rtx x1 ATTRIBUTE_UNUSED, rtx_insn *insn ATTRIBUTE_UNUSED)\n");
      break;

    case PEEPHOLE2:
      if (proc_id)
	printf ("static rtx_insn *\npeephole2_%d", proc_id);
      else
	printf ("rtx_insn *\npeephole2_insns");
      printf (" (rtx x1 ATTRIBUTE_UNUSED,\n"
	      "\trtx_insn *insn ATTRIBUTE_UNUSED,\n"
	      "\tint *pmatch_len_ ATTRIBUTE_UNUSED)\n");
      break;
    }
  print_subroutine_start (os, s, &root_pos);
  if (proc_id == 0)
    {
      printf ("  recog_data.insn = NULL;\n");
    }
  print_state (os, s, 2, true);
  printf ("}\n");
}

/* Print out a routine of type TYPE that performs ROOT.  */

static void
print_subroutine_group (output_state *os, routine_type type, state *root)
{
  os->type = type;
  if (use_subroutines_p)
    {
      /* Split ROOT up into smaller pieces, both for readability and to
	 help the compiler.  */
      auto_vec <state *> subroutines;
      find_subroutines (type, root, subroutines);

      /* Output the subroutines (but not ROOT itself).  */
      unsigned int i;
      state *s;
      FOR_EACH_VEC_ELT (subroutines, i, s)
	print_subroutine (os, s, i + 1);
    }
  /* Output the main routine.  */
  print_subroutine (os, root, 0);
}

/* Return the rtx pattern for the list of rtxes in a define_peephole2.  */

static rtx
get_peephole2_pattern (md_rtx_info *info)
{
  int i, j;
  rtvec vec = XVEC (info->def, 0);
  rtx pattern = rtx_alloc (SEQUENCE);
  XVEC (pattern, 0) = rtvec_alloc (GET_NUM_ELEM (vec));
  for (i = j = 0; i < GET_NUM_ELEM (vec); i++)
    {
      rtx x = RTVEC_ELT (vec, i);
      /* Ignore scratch register requirements.  */
      if (GET_CODE (x) != MATCH_SCRATCH && GET_CODE (x) != MATCH_DUP)
	{
	  XVECEXP (pattern, 0, j) = x;
	  j++;
	}
    }
  XVECLEN (pattern, 0) = j;
  if (j == 0)
    error_at (info->loc, "empty define_peephole2");
  return pattern;
}

/* Return true if *PATTERN_PTR is a PARALLEL in which at least one trailing
   rtx can be added automatically by add_clobbers.  If so, update
   *ACCEPTANCE_PTR so that its num_clobbers field contains the number
   of such trailing rtxes and update *PATTERN_PTR so that it contains
   the pattern without those rtxes.  */

static bool
remove_clobbers (acceptance_type *acceptance_ptr, rtx *pattern_ptr)
{
  int i;
  rtx new_pattern;

  /* Find the last non-clobber in the parallel.  */
  rtx pattern = *pattern_ptr;
  for (i = XVECLEN (pattern, 0); i > 0; i--)
    {
      rtx x = XVECEXP (pattern, 0, i - 1);
      if (GET_CODE (x) != CLOBBER
	  || (!REG_P (XEXP (x, 0))
	      && GET_CODE (XEXP (x, 0)) != MATCH_SCRATCH))
	break;
    }

  if (i == XVECLEN (pattern, 0))
    return false;

  /* Build a similar insn without the clobbers.  */
  if (i == 1)
    new_pattern = XVECEXP (pattern, 0, 0);
  else
    {
      new_pattern = rtx_alloc (PARALLEL);
      XVEC (new_pattern, 0) = rtvec_alloc (i);
      for (int j = 0; j < i; ++j)
	XVECEXP (new_pattern, 0, j) = XVECEXP (pattern, 0, j);
    }

  /* Recognize it.  */
  acceptance_ptr->u.full.u.num_clobbers = XVECLEN (pattern, 0) - i;
  *pattern_ptr = new_pattern;
  return true;
}

int
main (int argc, const char **argv)
{
  state insn_root, split_root, peephole2_root;

  progname = "genrecog";

  if (!init_rtx_reader_args (argc, argv))
    return (FATAL_EXIT_CODE);

  write_header ();

  /* Read the machine description.  */

  md_rtx_info info;
  while (read_md_rtx (&info))
    {
      rtx def = info.def;

      acceptance_type acceptance;
      acceptance.partial_p = false;
      acceptance.u.full.code = info.index;

      rtx pattern;
      switch (GET_CODE (def))
	{
	case DEFINE_INSN:
	  {
	    /* Match the instruction in the original .md form.  */
	    acceptance.type = RECOG;
	    acceptance.u.full.u.num_clobbers = 0;
	    pattern = add_implicit_parallel (XVEC (def, 1));
	    validate_pattern (pattern, &info, NULL_RTX, 0);
	    match_pattern (&insn_root, &info, pattern, acceptance);

	    /* If the pattern is a PARALLEL with trailing CLOBBERs,
	       allow recog_for_combine to match without the clobbers.  */
	    if (GET_CODE (pattern) == PARALLEL
		&& remove_clobbers (&acceptance, &pattern))
	      match_pattern (&insn_root, &info, pattern, acceptance);
	    break;
	  }

	case DEFINE_SPLIT:
	  acceptance.type = SPLIT;
	  pattern = add_implicit_parallel (XVEC (def, 0));
	  validate_pattern (pattern, &info, NULL_RTX, 0);
	  match_pattern (&split_root, &info, pattern, acceptance);

	  /* Declare the gen_split routine that we'll call if the
	     pattern matches.  The definition comes from insn-emit.c.  */
	  printf ("extern rtx_insn *gen_split_%d (rtx_insn *, rtx *);\n",
		  info.index);
	  break;

	case DEFINE_PEEPHOLE2:
	  acceptance.type = PEEPHOLE2;
	  pattern = get_peephole2_pattern (&info);
	  validate_pattern (pattern, &info, NULL_RTX, 0);
	  match_pattern (&peephole2_root, &info, pattern, acceptance);

	  /* Declare the gen_peephole2 routine that we'll call if the
	     pattern matches.  The definition comes from insn-emit.c.  */
	  printf ("extern rtx_insn *gen_peephole2_%d (rtx_insn *, rtx *);\n",
		  info.index);
	  break;

	default:
	  /* do nothing */;
	}
    }

  if (have_error)
    return FATAL_EXIT_CODE;

  puts ("\n\n");

  /* Optimize each routine in turn.  */
  optimize_subroutine_group ("recog", &insn_root);
  optimize_subroutine_group ("split_insns", &split_root);
  optimize_subroutine_group ("peephole2_insns", &peephole2_root);

  output_state os;
  os.id_to_var.safe_grow_cleared (num_positions, true);

  if (use_pattern_routines_p)
    {
      /* Look for common patterns and split them out into subroutines.  */
      auto_vec <merge_state_info> states;
      states.safe_push (&insn_root);
      states.safe_push (&split_root);
      states.safe_push (&peephole2_root);
      split_out_patterns (states);

      /* Print out the routines that we just created.  */
      unsigned int i;
      pattern_routine *routine;
      FOR_EACH_VEC_ELT (patterns, i, routine)
	print_pattern (&os, routine);
    }

  /* Print out the matching routines.  */
  print_subroutine_group (&os, RECOG, &insn_root);
  print_subroutine_group (&os, SPLIT, &split_root);
  print_subroutine_group (&os, PEEPHOLE2, &peephole2_root);

  fflush (stdout);
  return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
}
