/* Instruction scheduling pass.  This file computes dependencies between
   instructions.
   Copyright (C) 1992-2025 Free Software Foundation, Inc.
   Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
   and currently maintained by, Jim Wilson (wilson@cygnus.com)

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

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

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "df.h"
#include "insn-config.h"
#include "regs.h"
#include "memmodel.h"
#include "ira.h"
#include "ira-int.h"
#include "insn-attr.h"
#include "cfgbuild.h"
#include "sched-int.h"
#include "cselib.h"
#include "function-abi.h"

#ifdef INSN_SCHEDULING

/* Holds current parameters for the dependency analyzer.  */
struct sched_deps_info_def *sched_deps_info;

/* The data is specific to the Haifa scheduler.  */
vec<haifa_deps_insn_data_def>
    h_d_i_d = vNULL;

/* Return the major type present in the DS.  */
enum reg_note
ds_to_dk (ds_t ds)
{
  if (ds & DEP_TRUE)
    return REG_DEP_TRUE;

  if (ds & DEP_OUTPUT)
    return REG_DEP_OUTPUT;

  if (ds & DEP_CONTROL)
    return REG_DEP_CONTROL;

  gcc_assert (ds & DEP_ANTI);

  return REG_DEP_ANTI;
}

/* Return equivalent dep_status.  */
ds_t
dk_to_ds (enum reg_note dk)
{
  switch (dk)
    {
    case REG_DEP_TRUE:
      return DEP_TRUE;

    case REG_DEP_OUTPUT:
      return DEP_OUTPUT;

    case REG_DEP_CONTROL:
      return DEP_CONTROL;

    default:
      gcc_assert (dk == REG_DEP_ANTI);
      return DEP_ANTI;
    }
}

/* Functions to operate with dependence information container - dep_t.  */

/* Init DEP with the arguments.  */
void
init_dep_1 (dep_t dep, rtx_insn *pro, rtx_insn *con, enum reg_note type, ds_t ds)
{
  DEP_PRO (dep) = pro;
  DEP_CON (dep) = con;
  DEP_TYPE (dep) = type;
  DEP_STATUS (dep) = ds;
  DEP_COST (dep) = UNKNOWN_DEP_COST;
  DEP_NONREG (dep) = 0;
  DEP_MULTIPLE (dep) = 0;
  DEP_REPLACE (dep) = NULL;
  dep->unused = 0;
}

/* Init DEP with the arguments.
   While most of the scheduler (including targets) only need the major type
   of the dependency, it is convenient to hide full dep_status from them.  */
void
init_dep (dep_t dep, rtx_insn *pro, rtx_insn *con, enum reg_note kind)
{
  ds_t ds;

  if ((current_sched_info->flags & USE_DEPS_LIST))
    ds = dk_to_ds (kind);
  else
    ds = 0;

  init_dep_1 (dep, pro, con, kind, ds);
}

/* Make a copy of FROM in TO.  */
static void
copy_dep (dep_t to, dep_t from)
{
  memcpy (to, from, sizeof (*to));
}

static void dump_ds (FILE *, ds_t);

/* Define flags for dump_dep ().  */

/* Dump producer of the dependence.  */
#define DUMP_DEP_PRO (2)

/* Dump consumer of the dependence.  */
#define DUMP_DEP_CON (4)

/* Dump type of the dependence.  */
#define DUMP_DEP_TYPE (8)

/* Dump status of the dependence.  */
#define DUMP_DEP_STATUS (16)

/* Dump all information about the dependence.  */
#define DUMP_DEP_ALL (DUMP_DEP_PRO | DUMP_DEP_CON | DUMP_DEP_TYPE	\
		      |DUMP_DEP_STATUS)

/* Dump DEP to DUMP.
   FLAGS is a bit mask specifying what information about DEP needs
   to be printed.
   If FLAGS has the very first bit set, then dump all information about DEP
   and propagate this bit into the callee dump functions.  */
static void
dump_dep (FILE *dump, dep_t dep, int flags)
{
  if (flags & 1)
    flags |= DUMP_DEP_ALL;

  fprintf (dump, "<");

  if (flags & DUMP_DEP_PRO)
    fprintf (dump, "%d; ", INSN_UID (DEP_PRO (dep)));

  if (flags & DUMP_DEP_CON)
    fprintf (dump, "%d; ", INSN_UID (DEP_CON (dep)));

  if (flags & DUMP_DEP_TYPE)
    {
      char t;
      enum reg_note type = DEP_TYPE (dep);

      switch (type)
	{
	case REG_DEP_TRUE:
	  t = 't';
	  break;

	case REG_DEP_OUTPUT:
	  t = 'o';
	  break;

	case REG_DEP_CONTROL:
	  t = 'c';
	  break;

	case REG_DEP_ANTI:
	  t = 'a';
	  break;

	default:
	  gcc_unreachable ();
	  break;
	}

      fprintf (dump, "%c; ", t);
    }

  if (flags & DUMP_DEP_STATUS)
    {
      if (current_sched_info->flags & USE_DEPS_LIST)
	dump_ds (dump, DEP_STATUS (dep));
    }

  fprintf (dump, ">");
}

/* Default flags for dump_dep ().  */
static int dump_dep_flags = (DUMP_DEP_PRO | DUMP_DEP_CON);

/* Dump all fields of DEP to STDERR.  */
void
sd_debug_dep (dep_t dep)
{
  dump_dep (stderr, dep, 1);
  fprintf (stderr, "\n");
}

/* Determine whether DEP is a dependency link of a non-debug insn on a
   debug insn.  */

static inline bool
depl_on_debug_p (dep_link_t dep)
{
  return (DEBUG_INSN_P (DEP_LINK_PRO (dep))
	  && !DEBUG_INSN_P (DEP_LINK_CON (dep)));
}

/* Functions to operate with a single link from the dependencies lists -
   dep_link_t.  */

/* Attach L to appear after link X whose &DEP_LINK_NEXT (X) is given by
   PREV_NEXT_P.  */
static void
attach_dep_link (dep_link_t l, dep_link_t *prev_nextp)
{
  dep_link_t next = *prev_nextp;

  gcc_assert (DEP_LINK_PREV_NEXTP (l) == NULL
	      && DEP_LINK_NEXT (l) == NULL);

  /* Init node being inserted.  */
  DEP_LINK_PREV_NEXTP (l) = prev_nextp;
  DEP_LINK_NEXT (l) = next;

  /* Fix next node.  */
  if (next != NULL)
    {
      gcc_assert (DEP_LINK_PREV_NEXTP (next) == prev_nextp);

      DEP_LINK_PREV_NEXTP (next) = &DEP_LINK_NEXT (l);
    }

  /* Fix prev node.  */
  *prev_nextp = l;
}

/* Add dep_link LINK to deps_list L.  */
static void
add_to_deps_list (dep_link_t link, deps_list_t l)
{
  attach_dep_link (link, &DEPS_LIST_FIRST (l));

  /* Don't count debug deps.  */
  if (!depl_on_debug_p (link))
    ++DEPS_LIST_N_LINKS (l);
}

/* Detach dep_link L from the list.  */
static void
detach_dep_link (dep_link_t l)
{
  dep_link_t *prev_nextp = DEP_LINK_PREV_NEXTP (l);
  dep_link_t next = DEP_LINK_NEXT (l);

  *prev_nextp = next;

  if (next != NULL)
    DEP_LINK_PREV_NEXTP (next) = prev_nextp;

  DEP_LINK_PREV_NEXTP (l) = NULL;
  DEP_LINK_NEXT (l) = NULL;
}

/* Remove link LINK from list LIST.  */
static void
remove_from_deps_list (dep_link_t link, deps_list_t list)
{
  detach_dep_link (link);

  /* Don't count debug deps.  */
  if (!depl_on_debug_p (link))
    --DEPS_LIST_N_LINKS (list);
}

/* Move link LINK from list FROM to list TO.  */
static void
move_dep_link (dep_link_t link, deps_list_t from, deps_list_t to)
{
  remove_from_deps_list (link, from);
  add_to_deps_list (link, to);
}

/* Return true of LINK is not attached to any list.  */
static bool
dep_link_is_detached_p (dep_link_t link)
{
  return DEP_LINK_PREV_NEXTP (link) == NULL;
}

/* Pool to hold all dependency nodes (dep_node_t).  */
static object_allocator<_dep_node> *dn_pool;

/* Number of dep_nodes out there.  */
static int dn_pool_diff = 0;

/* Create a dep_node.  */
static dep_node_t
create_dep_node (void)
{
  dep_node_t n = dn_pool->allocate ();
  dep_link_t back = DEP_NODE_BACK (n);
  dep_link_t forw = DEP_NODE_FORW (n);

  DEP_LINK_NODE (back) = n;
  DEP_LINK_NEXT (back) = NULL;
  DEP_LINK_PREV_NEXTP (back) = NULL;

  DEP_LINK_NODE (forw) = n;
  DEP_LINK_NEXT (forw) = NULL;
  DEP_LINK_PREV_NEXTP (forw) = NULL;

  ++dn_pool_diff;

  return n;
}

/* Delete dep_node N.  N must not be connected to any deps_list.  */
static void
delete_dep_node (dep_node_t n)
{
  gcc_assert (dep_link_is_detached_p (DEP_NODE_BACK (n))
	      && dep_link_is_detached_p (DEP_NODE_FORW (n)));

  XDELETE (DEP_REPLACE (DEP_NODE_DEP (n)));

  --dn_pool_diff;

  dn_pool->remove (n);
}

/* Pool to hold dependencies lists (deps_list_t).  */
static object_allocator<_deps_list> *dl_pool;

/* Number of deps_lists out there.  */
static int dl_pool_diff = 0;

/* Functions to operate with dependences lists - deps_list_t.  */

/* Return true if list L is empty.  */
static bool
deps_list_empty_p (deps_list_t l)
{
  return DEPS_LIST_N_LINKS (l) == 0;
}

/* Create a new deps_list.  */
static deps_list_t
create_deps_list (void)
{
  deps_list_t l = dl_pool->allocate ();

  DEPS_LIST_FIRST (l) = NULL;
  DEPS_LIST_N_LINKS (l) = 0;

  ++dl_pool_diff;
  return l;
}

/* Free deps_list L.  */
static void
free_deps_list (deps_list_t l)
{
  gcc_assert (deps_list_empty_p (l));

  --dl_pool_diff;

  dl_pool->remove (l);
}

/* Return true if there is no dep_nodes and deps_lists out there.
   After the region is scheduled all the dependency nodes and lists
   should [generally] be returned to pool.  */
bool
deps_pools_are_empty_p (void)
{
  return dn_pool_diff == 0 && dl_pool_diff == 0;
}

/* Remove all elements from L.  */
static void
clear_deps_list (deps_list_t l)
{
  do
    {
      dep_link_t link = DEPS_LIST_FIRST (l);

      if (link == NULL)
	break;

      remove_from_deps_list (link, l);
    }
  while (1);
}

/* Decide whether a dependency should be treated as a hard or a speculative
   dependency.  */
static bool
dep_spec_p (dep_t dep)
{
  if (current_sched_info->flags & DO_SPECULATION)
    {
      if (DEP_STATUS (dep) & SPECULATIVE)
	return true;
    }
  if (current_sched_info->flags & DO_PREDICATION)
    {
      if (DEP_TYPE (dep) == REG_DEP_CONTROL)
	return true;
    }
  if (DEP_REPLACE (dep) != NULL)
    return true;
  return false;
}

static regset reg_pending_sets;
static regset reg_pending_clobbers;
static regset reg_pending_uses;
static regset reg_pending_control_uses;
static enum reg_pending_barrier_mode reg_pending_barrier;

/* Hard registers implicitly clobbered or used (or may be implicitly
   clobbered or used) by the currently analyzed insn.  For example,
   insn in its constraint has one register class.  Even if there is
   currently no hard register in the insn, the particular hard
   register will be in the insn after reload pass because the
   constraint requires it.  */
static HARD_REG_SET implicit_reg_pending_clobbers;
static HARD_REG_SET implicit_reg_pending_uses;

/* To speed up the test for duplicate dependency links we keep a
   record of dependencies created by add_dependence when the average
   number of instructions in a basic block is very large.

   Studies have shown that there is typically around 5 instructions between
   branches for typical C code.  So we can make a guess that the average
   basic block is approximately 5 instructions long; we will choose 100X
   the average size as a very large basic block.

   Each insn has associated bitmaps for its dependencies.  Each bitmap
   has enough entries to represent a dependency on any other insn in
   the insn chain.  All bitmap for true dependencies cache is
   allocated then the rest two ones are also allocated.  */
static bitmap true_dependency_cache = NULL;
static bitmap output_dependency_cache = NULL;
static bitmap anti_dependency_cache = NULL;
static bitmap control_dependency_cache = NULL;
static bitmap spec_dependency_cache = NULL;
static int cache_size;

/* True if we should mark added dependencies as a non-register deps.  */
static bool mark_as_hard;

static bool deps_may_trap_p (const_rtx);
static void add_dependence_1 (rtx_insn *, rtx_insn *, enum reg_note);
static void add_dependence_list (rtx_insn *, rtx_insn_list *, int,
				 enum reg_note, bool);
static void add_dependence_list_and_free (class deps_desc *, rtx_insn *,
					  rtx_insn_list **, int, enum reg_note,
					  bool);
static void delete_all_dependences (rtx_insn *);
static void chain_to_prev_insn (rtx_insn *);

static void flush_pending_lists (class deps_desc *, rtx_insn *, int, int);
static void sched_analyze_1 (class deps_desc *, rtx, rtx_insn *);
static void sched_analyze_2 (class deps_desc *, rtx, rtx_insn *);
static void sched_analyze_insn (class deps_desc *, rtx, rtx_insn *);

static bool sched_has_condition_p (const rtx_insn *);
static bool conditions_mutex_p (const_rtx, const_rtx, bool, bool);

static enum DEPS_ADJUST_RESULT maybe_add_or_update_dep_1 (dep_t, bool,
							  rtx, rtx);
static enum DEPS_ADJUST_RESULT add_or_update_dep_1 (dep_t, bool, rtx, rtx);

static void check_dep (dep_t, bool);


/* Return true if a load of the memory reference MEM can cause a trap.  */

static bool
deps_may_trap_p (const_rtx mem)
{
  const_rtx addr = XEXP (mem, 0);

  if (REG_P (addr) && REGNO (addr) >= FIRST_PSEUDO_REGISTER)
    {
      const_rtx t = get_reg_known_value (REGNO (addr));
      if (t)
	addr = t;
    }
  return rtx_addr_can_trap_p (addr);
}


/* Find the condition under which INSN is executed.  If REV is not NULL,
   it is set to TRUE when the returned comparison should be reversed
   to get the actual condition.  */
static rtx
sched_get_condition_with_rev_uncached (const rtx_insn *insn, bool *rev)
{
  rtx pat = PATTERN (insn);
  rtx src;

  if (rev)
    *rev = false;

  if (GET_CODE (pat) == COND_EXEC)
    return COND_EXEC_TEST (pat);

  if (!any_condjump_p (insn) || !onlyjump_p (insn))
    return 0;

  src = SET_SRC (pc_set (insn));

  if (XEXP (src, 2) == pc_rtx)
    return XEXP (src, 0);
  else if (XEXP (src, 1) == pc_rtx)
    {
      rtx cond = XEXP (src, 0);
      enum rtx_code revcode = reversed_comparison_code (cond, insn);

      if (revcode == UNKNOWN)
	return 0;

      if (rev)
	*rev = true;
      return cond;
    }

  return 0;
}

/* Return the condition under which INSN does not execute (i.e.  the
   not-taken condition for a conditional branch), or NULL if we cannot
   find such a condition.  The caller should make a copy of the condition
   before using it.  */
rtx
sched_get_reverse_condition_uncached (const rtx_insn *insn)
{
  bool rev;
  rtx cond = sched_get_condition_with_rev_uncached (insn, &rev);
  if (cond == NULL_RTX)
    return cond;
  if (!rev)
    {
      enum rtx_code revcode = reversed_comparison_code (cond, insn);
      cond = gen_rtx_fmt_ee (revcode, GET_MODE (cond),
			     XEXP (cond, 0),
			     XEXP (cond, 1));
    }
  return cond;
}

/* Caching variant of sched_get_condition_with_rev_uncached.
   We only do actual work the first time we come here for an insn; the
   results are cached in INSN_CACHED_COND and INSN_REVERSE_COND.  */
static rtx
sched_get_condition_with_rev (const rtx_insn *insn, bool *rev)
{
  bool tmp;

  if (INSN_LUID (insn) == 0)
    return sched_get_condition_with_rev_uncached (insn, rev);

  if (INSN_CACHED_COND (insn) == const_true_rtx)
    return NULL_RTX;

  if (INSN_CACHED_COND (insn) != NULL_RTX)
    {
      if (rev)
	*rev = INSN_REVERSE_COND (insn);
      return INSN_CACHED_COND (insn);
    }

  INSN_CACHED_COND (insn) = sched_get_condition_with_rev_uncached (insn, &tmp);
  INSN_REVERSE_COND (insn) = tmp;

  if (INSN_CACHED_COND (insn) == NULL_RTX)
    {
      INSN_CACHED_COND (insn) = const_true_rtx;
      return NULL_RTX;
    }

  if (rev)
    *rev = INSN_REVERSE_COND (insn);
  return INSN_CACHED_COND (insn);
}

/* True when we can find a condition under which INSN is executed.  */
static bool
sched_has_condition_p (const rtx_insn *insn)
{
  return !! sched_get_condition_with_rev (insn, NULL);
}



/* Return true if conditions COND1 and COND2 can never be both true.  */
static bool
conditions_mutex_p (const_rtx cond1, const_rtx cond2, bool rev1, bool rev2)
{
  if (COMPARISON_P (cond1)
      && COMPARISON_P (cond2)
      && GET_CODE (cond1) ==
	  (rev1==rev2
	  ? reversed_comparison_code (cond2, NULL)
	  : GET_CODE (cond2))
      && rtx_equal_p (XEXP (cond1, 0), XEXP (cond2, 0))
      && XEXP (cond1, 1) == XEXP (cond2, 1))
    return true;
  return false;
}

/* Return true if insn1 and insn2 can never depend on one another because
   the conditions under which they are executed are mutually exclusive.  */
bool
sched_insns_conditions_mutex_p (const rtx_insn *insn1, const rtx_insn *insn2)
{
  rtx cond1, cond2;
  bool rev1 = false, rev2 = false;

  /* df doesn't handle conditional lifetimes entirely correctly;
     calls mess up the conditional lifetimes.  */
  if (!CALL_P (insn1) && !CALL_P (insn2))
    {
      cond1 = sched_get_condition_with_rev (insn1, &rev1);
      cond2 = sched_get_condition_with_rev (insn2, &rev2);
      if (cond1 && cond2
	  && conditions_mutex_p (cond1, cond2, rev1, rev2)
	  /* Make sure first instruction doesn't affect condition of second
	     instruction if switched.  */
	  && !modified_in_p (cond1, insn2)
	  /* Make sure second instruction doesn't affect condition of first
	     instruction if switched.  */
	  && !modified_in_p (cond2, insn1))
	return true;
    }
  return false;
}


/* Return true if INSN can potentially be speculated with type DS.  */
bool
sched_insn_is_legitimate_for_speculation_p (const rtx_insn *insn, ds_t ds)
{
  if (HAS_INTERNAL_DEP (insn))
    return false;

  if (!NONJUMP_INSN_P (insn))
    return false;

  if (SCHED_GROUP_P (insn))
    return false;

  if (IS_SPECULATION_CHECK_P (CONST_CAST_RTX_INSN (insn)))
    return false;

  if (side_effects_p (PATTERN (insn)))
    return false;

  if (ds & BE_IN_SPEC)
    /* The following instructions, which depend on a speculatively scheduled
       instruction, cannot be speculatively scheduled along.  */
    {
      if (may_trap_or_fault_p (PATTERN (insn)))
	/* If instruction might fault, it cannot be speculatively scheduled.
	   For control speculation it's obvious why and for data speculation
	   it's because the insn might get wrong input if speculation
	   wasn't successful.  */
	return false;

      if ((ds & BE_IN_DATA)
	  && sched_has_condition_p (insn))
	/* If this is a predicated instruction, then it cannot be
	   speculatively scheduled.  See PR35659.  */
	return false;
    }

  return true;
}

/* Initialize LIST_PTR to point to one of the lists present in TYPES_PTR,
   initialize RESOLVED_P_PTR with true if that list consists of resolved deps,
   and remove the type of returned [through LIST_PTR] list from TYPES_PTR.
   This function is used to switch sd_iterator to the next list.
   !!! For internal use only.  Might consider moving it to sched-int.h.  */
void
sd_next_list (const_rtx insn, sd_list_types_def *types_ptr,
	      deps_list_t *list_ptr, bool *resolved_p_ptr)
{
  sd_list_types_def types = *types_ptr;

  if (types & SD_LIST_HARD_BACK)
    {
      *list_ptr = INSN_HARD_BACK_DEPS (insn);
      *resolved_p_ptr = false;
      *types_ptr = types & ~SD_LIST_HARD_BACK;
    }
  else if (types & SD_LIST_SPEC_BACK)
    {
      *list_ptr = INSN_SPEC_BACK_DEPS (insn);
      *resolved_p_ptr = false;
      *types_ptr = types & ~SD_LIST_SPEC_BACK;
    }
  else if (types & SD_LIST_FORW)
    {
      *list_ptr = INSN_FORW_DEPS (insn);
      *resolved_p_ptr = false;
      *types_ptr = types & ~SD_LIST_FORW;
    }
  else if (types & SD_LIST_RES_BACK)
    {
      *list_ptr = INSN_RESOLVED_BACK_DEPS (insn);
      *resolved_p_ptr = true;
      *types_ptr = types & ~SD_LIST_RES_BACK;
    }
  else if (types & SD_LIST_RES_FORW)
    {
      *list_ptr = INSN_RESOLVED_FORW_DEPS (insn);
      *resolved_p_ptr = true;
      *types_ptr = types & ~SD_LIST_RES_FORW;
    }
  else
    {
      *list_ptr = NULL;
      *resolved_p_ptr = false;
      *types_ptr = SD_LIST_NONE;
    }
}

/* Return the summary size of INSN's lists defined by LIST_TYPES.  */
int
sd_lists_size (const_rtx insn, sd_list_types_def list_types)
{
  int size = 0;

  while (list_types != SD_LIST_NONE)
    {
      deps_list_t list;
      bool resolved_p;

      sd_next_list (insn, &list_types, &list, &resolved_p);
      if (list)
	size += DEPS_LIST_N_LINKS (list);
    }

  return size;
}

/* Return true if INSN's lists defined by LIST_TYPES are all empty.  */

bool
sd_lists_empty_p (const_rtx insn, sd_list_types_def list_types)
{
  while (list_types != SD_LIST_NONE)
    {
      deps_list_t list;
      bool resolved_p;

      sd_next_list (insn, &list_types, &list, &resolved_p);
      if (!deps_list_empty_p (list))
	return false;
    }

  return true;
}

/* Initialize data for INSN.  */
void
sd_init_insn (rtx_insn *insn)
{
  INSN_HARD_BACK_DEPS (insn) = create_deps_list ();
  INSN_SPEC_BACK_DEPS (insn) = create_deps_list ();
  INSN_RESOLVED_BACK_DEPS (insn) = create_deps_list ();
  INSN_FORW_DEPS (insn) = create_deps_list ();
  INSN_RESOLVED_FORW_DEPS (insn) = create_deps_list ();

  /* ??? It would be nice to allocate dependency caches here.  */
}

/* Free data for INSN.  */
void
sd_finish_insn (rtx_insn *insn)
{
  /* ??? It would be nice to deallocate dependency caches here.  */

  free_deps_list (INSN_HARD_BACK_DEPS (insn));
  INSN_HARD_BACK_DEPS (insn) = NULL;

  free_deps_list (INSN_SPEC_BACK_DEPS (insn));
  INSN_SPEC_BACK_DEPS (insn) = NULL;

  free_deps_list (INSN_RESOLVED_BACK_DEPS (insn));
  INSN_RESOLVED_BACK_DEPS (insn) = NULL;

  free_deps_list (INSN_FORW_DEPS (insn));
  INSN_FORW_DEPS (insn) = NULL;

  free_deps_list (INSN_RESOLVED_FORW_DEPS (insn));
  INSN_RESOLVED_FORW_DEPS (insn) = NULL;
}

/* Find a dependency between producer PRO and consumer CON.
   Search through resolved dependency lists if RESOLVED_P is true.
   If no such dependency is found return NULL,
   otherwise return the dependency and initialize SD_IT_PTR [if it is nonnull]
   with an iterator pointing to it.  */
static dep_t
sd_find_dep_between_no_cache (rtx pro, rtx con, bool resolved_p,
			      sd_iterator_def *sd_it_ptr)
{
  sd_list_types_def pro_list_type;
  sd_list_types_def con_list_type;
  sd_iterator_def sd_it;
  dep_t dep;
  bool found_p = false;

  if (resolved_p)
    {
      pro_list_type = SD_LIST_RES_FORW;
      con_list_type = SD_LIST_RES_BACK;
    }
  else
    {
      pro_list_type = SD_LIST_FORW;
      con_list_type = SD_LIST_BACK;
    }

  /* Walk through either back list of INSN or forw list of ELEM
     depending on which one is shorter.  */
  if (sd_lists_size (con, con_list_type) < sd_lists_size (pro, pro_list_type))
    {
      /* Find the dep_link with producer PRO in consumer's back_deps.  */
      FOR_EACH_DEP (con, con_list_type, sd_it, dep)
	if (DEP_PRO (dep) == pro)
	  {
	    found_p = true;
	    break;
	  }
    }
  else
    {
      /* Find the dep_link with consumer CON in producer's forw_deps.  */
      FOR_EACH_DEP (pro, pro_list_type, sd_it, dep)
	if (DEP_CON (dep) == con)
	  {
	    found_p = true;
	    break;
	  }
    }

  if (found_p)
    {
      if (sd_it_ptr != NULL)
	*sd_it_ptr = sd_it;

      return dep;
    }

  return NULL;
}

/* Find a dependency between producer PRO and consumer CON.
   Use dependency [if available] to check if dependency is present at all.
   Search through resolved dependency lists if RESOLVED_P is true.
   If the dependency or NULL if none found.  */
dep_t
sd_find_dep_between (rtx pro, rtx con, bool resolved_p)
{
  if (true_dependency_cache != NULL)
    /* Avoiding the list walk below can cut compile times dramatically
       for some code.  */
    {
      int elem_luid = INSN_LUID (pro);
      int insn_luid = INSN_LUID (con);

      if (!bitmap_bit_p (&true_dependency_cache[insn_luid], elem_luid)
	  && !bitmap_bit_p (&output_dependency_cache[insn_luid], elem_luid)
	  && !bitmap_bit_p (&anti_dependency_cache[insn_luid], elem_luid)
	  && !bitmap_bit_p (&control_dependency_cache[insn_luid], elem_luid))
	return NULL;
    }

  return sd_find_dep_between_no_cache (pro, con, resolved_p, NULL);
}

/* Add or update  a dependence described by DEP.
   MEM1 and MEM2, if non-null, correspond to memory locations in case of
   data speculation.

   The function returns a value indicating if an old entry has been changed
   or a new entry has been added to insn's backward deps.

   This function merely checks if producer and consumer is the same insn
   and doesn't create a dep in this case.  Actual manipulation of
   dependence data structures is performed in add_or_update_dep_1.  */
static enum DEPS_ADJUST_RESULT
maybe_add_or_update_dep_1 (dep_t dep, bool resolved_p, rtx mem1, rtx mem2)
{
  rtx_insn *elem = DEP_PRO (dep);
  rtx_insn *insn = DEP_CON (dep);

  gcc_assert (INSN_P (insn) && INSN_P (elem));

  /* Don't depend an insn on itself.  */
  if (insn == elem)
    {
      if (sched_deps_info->generate_spec_deps)
        /* INSN has an internal dependence, which we can't overcome.  */
        HAS_INTERNAL_DEP (insn) = 1;

      return DEP_NODEP;
    }

  return add_or_update_dep_1 (dep, resolved_p, mem1, mem2);
}

/* Ask dependency caches what needs to be done for dependence DEP.
   Return DEP_CREATED if new dependence should be created and there is no
   need to try to find one searching the dependencies lists.
   Return DEP_PRESENT if there already is a dependence described by DEP and
   hence nothing is to be done.
   Return DEP_CHANGED if there already is a dependence, but it should be
   updated to incorporate additional information from DEP.  */
static enum DEPS_ADJUST_RESULT
ask_dependency_caches (dep_t dep)
{
  int elem_luid = INSN_LUID (DEP_PRO (dep));
  int insn_luid = INSN_LUID (DEP_CON (dep));

  gcc_assert (true_dependency_cache != NULL
	      && output_dependency_cache != NULL
	      && anti_dependency_cache != NULL
	      && control_dependency_cache != NULL);

  if (!(current_sched_info->flags & USE_DEPS_LIST))
    {
      enum reg_note present_dep_type;

      if (bitmap_bit_p (&true_dependency_cache[insn_luid], elem_luid))
	present_dep_type = REG_DEP_TRUE;
      else if (bitmap_bit_p (&output_dependency_cache[insn_luid], elem_luid))
	present_dep_type = REG_DEP_OUTPUT;
      else if (bitmap_bit_p (&anti_dependency_cache[insn_luid], elem_luid))
	present_dep_type = REG_DEP_ANTI;
      else if (bitmap_bit_p (&control_dependency_cache[insn_luid], elem_luid))
	present_dep_type = REG_DEP_CONTROL;
      else
	/* There is no existing dep so it should be created.  */
	return DEP_CREATED;

      if ((int) DEP_TYPE (dep) >= (int) present_dep_type)
	/* DEP does not add anything to the existing dependence.  */
	return DEP_PRESENT;
    }
  else
    {
      ds_t present_dep_types = 0;

      if (bitmap_bit_p (&true_dependency_cache[insn_luid], elem_luid))
	present_dep_types |= DEP_TRUE;
      if (bitmap_bit_p (&output_dependency_cache[insn_luid], elem_luid))
	present_dep_types |= DEP_OUTPUT;
      if (bitmap_bit_p (&anti_dependency_cache[insn_luid], elem_luid))
	present_dep_types |= DEP_ANTI;
      if (bitmap_bit_p (&control_dependency_cache[insn_luid], elem_luid))
	present_dep_types |= DEP_CONTROL;

      if (present_dep_types == 0)
	/* There is no existing dep so it should be created.  */
	return DEP_CREATED;

      if (!(current_sched_info->flags & DO_SPECULATION)
	  || !bitmap_bit_p (&spec_dependency_cache[insn_luid], elem_luid))
	{
	  if ((present_dep_types | (DEP_STATUS (dep) & DEP_TYPES))
	      == present_dep_types)
	    /* DEP does not add anything to the existing dependence.  */
	    return DEP_PRESENT;
	}
      else
	{
	  /* Only true dependencies can be data speculative and
	     only anti dependencies can be control speculative.  */
	  gcc_assert ((present_dep_types & (DEP_TRUE | DEP_ANTI))
		      == present_dep_types);

	  /* if (DEP is SPECULATIVE) then
	     ..we should update DEP_STATUS
	     else
	     ..we should reset existing dep to non-speculative.  */
	}
    }

  return DEP_CHANGED;
}

/* Set dependency caches according to DEP.  */
static void
set_dependency_caches (dep_t dep)
{
  int elem_luid = INSN_LUID (DEP_PRO (dep));
  int insn_luid = INSN_LUID (DEP_CON (dep));

  if (!(current_sched_info->flags & USE_DEPS_LIST))
    {
      switch (DEP_TYPE (dep))
	{
	case REG_DEP_TRUE:
	  bitmap_set_bit (&true_dependency_cache[insn_luid], elem_luid);
	  break;

	case REG_DEP_OUTPUT:
	  bitmap_set_bit (&output_dependency_cache[insn_luid], elem_luid);
	  break;

	case REG_DEP_ANTI:
	  bitmap_set_bit (&anti_dependency_cache[insn_luid], elem_luid);
	  break;

	case REG_DEP_CONTROL:
	  bitmap_set_bit (&control_dependency_cache[insn_luid], elem_luid);
	  break;

	default:
	  gcc_unreachable ();
	}
    }
  else
    {
      ds_t ds = DEP_STATUS (dep);

      if (ds & DEP_TRUE)
	bitmap_set_bit (&true_dependency_cache[insn_luid], elem_luid);
      if (ds & DEP_OUTPUT)
	bitmap_set_bit (&output_dependency_cache[insn_luid], elem_luid);
      if (ds & DEP_ANTI)
	bitmap_set_bit (&anti_dependency_cache[insn_luid], elem_luid);
      if (ds & DEP_CONTROL)
	bitmap_set_bit (&control_dependency_cache[insn_luid], elem_luid);

      if (ds & SPECULATIVE)
	{
	  gcc_assert (current_sched_info->flags & DO_SPECULATION);
	  bitmap_set_bit (&spec_dependency_cache[insn_luid], elem_luid);
	}
    }
}

/* Type of dependence DEP have changed from OLD_TYPE.  Update dependency
   caches accordingly.  */
static void
update_dependency_caches (dep_t dep, enum reg_note old_type)
{
  int elem_luid = INSN_LUID (DEP_PRO (dep));
  int insn_luid = INSN_LUID (DEP_CON (dep));

  /* Clear corresponding cache entry because type of the link
     may have changed.  Keep them if we use_deps_list.  */
  if (!(current_sched_info->flags & USE_DEPS_LIST))
    {
      switch (old_type)
	{
	case REG_DEP_OUTPUT:
	  bitmap_clear_bit (&output_dependency_cache[insn_luid], elem_luid);
	  break;

	case REG_DEP_ANTI:
	  bitmap_clear_bit (&anti_dependency_cache[insn_luid], elem_luid);
	  break;

	case REG_DEP_CONTROL:
	  bitmap_clear_bit (&control_dependency_cache[insn_luid], elem_luid);
	  break;

	default:
	  gcc_unreachable ();
	}
    }

  set_dependency_caches (dep);
}

/* Convert a dependence pointed to by SD_IT to be non-speculative.  */
static void
change_spec_dep_to_hard (sd_iterator_def sd_it)
{
  dep_node_t node = DEP_LINK_NODE (*sd_it.linkp);
  dep_link_t link = DEP_NODE_BACK (node);
  dep_t dep = DEP_NODE_DEP (node);
  rtx_insn *elem = DEP_PRO (dep);
  rtx_insn *insn = DEP_CON (dep);

  move_dep_link (link, INSN_SPEC_BACK_DEPS (insn), INSN_HARD_BACK_DEPS (insn));

  DEP_STATUS (dep) &= ~SPECULATIVE;

  if (true_dependency_cache != NULL)
    /* Clear the cache entry.  */
    bitmap_clear_bit (&spec_dependency_cache[INSN_LUID (insn)],
		      INSN_LUID (elem));
}

/* Update DEP to incorporate information from NEW_DEP.
   SD_IT points to DEP in case it should be moved to another list.
   MEM1 and MEM2, if nonnull, correspond to memory locations in case if
   data-speculative dependence should be updated.  */
static enum DEPS_ADJUST_RESULT
update_dep (dep_t dep, dep_t new_dep,
	    sd_iterator_def sd_it ATTRIBUTE_UNUSED,
	    rtx mem1 ATTRIBUTE_UNUSED,
	    rtx mem2 ATTRIBUTE_UNUSED)
{
  enum DEPS_ADJUST_RESULT res = DEP_PRESENT;
  enum reg_note old_type = DEP_TYPE (dep);
  bool was_spec = dep_spec_p (dep);

  DEP_NONREG (dep) |= DEP_NONREG (new_dep);
  DEP_MULTIPLE (dep) = 1;

  /* If this is a more restrictive type of dependence than the
     existing one, then change the existing dependence to this
     type.  */
  if ((int) DEP_TYPE (new_dep) < (int) old_type)
    {
      DEP_TYPE (dep) = DEP_TYPE (new_dep);
      res = DEP_CHANGED;
    }

  if (current_sched_info->flags & USE_DEPS_LIST)
    /* Update DEP_STATUS.  */
    {
      ds_t dep_status = DEP_STATUS (dep);
      ds_t ds = DEP_STATUS (new_dep);
      ds_t new_status = ds | dep_status;

      if (new_status & SPECULATIVE)
	{
	  /* Either existing dep or a dep we're adding or both are
	     speculative.  */
	  if (!(ds & SPECULATIVE)
	      || !(dep_status & SPECULATIVE))
	    /* The new dep can't be speculative.  */
	    new_status &= ~SPECULATIVE;
	  else
	    {
	      /* Both are speculative.  Merge probabilities.  */
	      if (mem1 != NULL)
		{
		  dw_t dw;

		  dw = estimate_dep_weak (mem1, mem2);
		  ds = set_dep_weak (ds, BEGIN_DATA, dw);
		}

	      new_status = ds_merge (dep_status, ds);
	    }
	}

      ds = new_status;

      if (dep_status != ds)
	{
	  DEP_STATUS (dep) = ds;
	  res = DEP_CHANGED;
	}
    }

  if (was_spec && !dep_spec_p (dep))
    /* The old dep was speculative, but now it isn't.  */
    change_spec_dep_to_hard (sd_it);

  if (true_dependency_cache != NULL
      && res == DEP_CHANGED)
    update_dependency_caches (dep, old_type);

  return res;
}

/* Add or update  a dependence described by DEP.
   MEM1 and MEM2, if non-null, correspond to memory locations in case of
   data speculation.

   The function returns a value indicating if an old entry has been changed
   or a new entry has been added to insn's backward deps or nothing has
   been updated at all.  */
static enum DEPS_ADJUST_RESULT
add_or_update_dep_1 (dep_t new_dep, bool resolved_p,
		     rtx mem1 ATTRIBUTE_UNUSED, rtx mem2 ATTRIBUTE_UNUSED)
{
  bool maybe_present_p = true;
  bool present_p = false;

  gcc_assert (INSN_P (DEP_PRO (new_dep)) && INSN_P (DEP_CON (new_dep))
	      && DEP_PRO (new_dep) != DEP_CON (new_dep));

  if (flag_checking)
    check_dep (new_dep, mem1 != NULL);

  if (true_dependency_cache != NULL)
    {
      switch (ask_dependency_caches (new_dep))
	{
	case DEP_PRESENT:
	  dep_t present_dep;
	  sd_iterator_def sd_it;

	  present_dep = sd_find_dep_between_no_cache (DEP_PRO (new_dep),
						      DEP_CON (new_dep),
						      resolved_p, &sd_it);
	  DEP_MULTIPLE (present_dep) = 1;
	  return DEP_PRESENT;

	case DEP_CHANGED:
	  maybe_present_p = true;
	  present_p = true;
	  break;

	case DEP_CREATED:
	  maybe_present_p = false;
	  present_p = false;
	  break;

	default:
	  gcc_unreachable ();
	  break;
	}
    }

  /* Check that we don't already have this dependence.  */
  if (maybe_present_p)
    {
      dep_t present_dep;
      sd_iterator_def sd_it;

      gcc_assert (true_dependency_cache == NULL || present_p);

      present_dep = sd_find_dep_between_no_cache (DEP_PRO (new_dep),
						  DEP_CON (new_dep),
						  resolved_p, &sd_it);

      if (present_dep != NULL)
	/* We found an existing dependency between ELEM and INSN.  */
	return update_dep (present_dep, new_dep, sd_it, mem1, mem2);
      else
	/* We didn't find a dep, it shouldn't present in the cache.  */
	gcc_assert (!present_p);
    }

  /* Might want to check one level of transitivity to save conses.
     This check should be done in maybe_add_or_update_dep_1.
     Since we made it to add_or_update_dep_1, we must create
     (or update) a link.  */

  if (mem1 != NULL_RTX)
    {
      gcc_assert (sched_deps_info->generate_spec_deps);
      DEP_STATUS (new_dep) = set_dep_weak (DEP_STATUS (new_dep), BEGIN_DATA,
					   estimate_dep_weak (mem1, mem2));
    }

  sd_add_dep (new_dep, resolved_p);

  return DEP_CREATED;
}

/* Initialize BACK_LIST_PTR with consumer's backward list and
   FORW_LIST_PTR with producer's forward list.  If RESOLVED_P is true
   initialize with lists that hold resolved deps.  */
static void
get_back_and_forw_lists (dep_t dep, bool resolved_p,
			 deps_list_t *back_list_ptr,
			 deps_list_t *forw_list_ptr)
{
  rtx_insn *con = DEP_CON (dep);

  if (!resolved_p)
    {
      if (dep_spec_p (dep))
	*back_list_ptr = INSN_SPEC_BACK_DEPS (con);
      else
	*back_list_ptr = INSN_HARD_BACK_DEPS (con);

      *forw_list_ptr = INSN_FORW_DEPS (DEP_PRO (dep));
    }
  else
    {
      *back_list_ptr = INSN_RESOLVED_BACK_DEPS (con);
      *forw_list_ptr = INSN_RESOLVED_FORW_DEPS (DEP_PRO (dep));
    }
}

/* Add dependence described by DEP.
   If RESOLVED_P is true treat the dependence as a resolved one.  */
void
sd_add_dep (dep_t dep, bool resolved_p)
{
  dep_node_t n = create_dep_node ();
  deps_list_t con_back_deps;
  deps_list_t pro_forw_deps;
  rtx_insn *elem = DEP_PRO (dep);
  rtx_insn *insn = DEP_CON (dep);

  gcc_assert (INSN_P (insn) && INSN_P (elem) && insn != elem);

  if ((current_sched_info->flags & DO_SPECULATION) == 0
      || !sched_insn_is_legitimate_for_speculation_p (insn, DEP_STATUS (dep)))
    DEP_STATUS (dep) &= ~SPECULATIVE;

  copy_dep (DEP_NODE_DEP (n), dep);

  get_back_and_forw_lists (dep, resolved_p, &con_back_deps, &pro_forw_deps);

  add_to_deps_list (DEP_NODE_BACK (n), con_back_deps);

  if (flag_checking)
    check_dep (dep, false);

  add_to_deps_list (DEP_NODE_FORW (n), pro_forw_deps);

  /* If we are adding a dependency to INSN's LOG_LINKs, then note that
     in the bitmap caches of dependency information.  */
  if (true_dependency_cache != NULL)
    set_dependency_caches (dep);
}

/* Add or update backward dependence between INSN and ELEM
   with given type DEP_TYPE and dep_status DS.
   This function is a convenience wrapper.  */
enum DEPS_ADJUST_RESULT
sd_add_or_update_dep (dep_t dep, bool resolved_p)
{
  return add_or_update_dep_1 (dep, resolved_p, NULL_RTX, NULL_RTX);
}

/* Resolved dependence pointed to by SD_IT.
   SD_IT will advance to the next element.  */
void
sd_resolve_dep (sd_iterator_def sd_it)
{
  dep_node_t node = DEP_LINK_NODE (*sd_it.linkp);
  dep_t dep = DEP_NODE_DEP (node);
  rtx_insn *pro = DEP_PRO (dep);
  rtx_insn *con = DEP_CON (dep);

  if (dep_spec_p (dep))
    move_dep_link (DEP_NODE_BACK (node), INSN_SPEC_BACK_DEPS (con),
		   INSN_RESOLVED_BACK_DEPS (con));
  else
    move_dep_link (DEP_NODE_BACK (node), INSN_HARD_BACK_DEPS (con),
		   INSN_RESOLVED_BACK_DEPS (con));

  move_dep_link (DEP_NODE_FORW (node), INSN_FORW_DEPS (pro),
		 INSN_RESOLVED_FORW_DEPS (pro));
}

/* Perform the inverse operation of sd_resolve_dep.  Restore the dependence
   pointed to by SD_IT to unresolved state.  */
void
sd_unresolve_dep (sd_iterator_def sd_it)
{
  dep_node_t node = DEP_LINK_NODE (*sd_it.linkp);
  dep_t dep = DEP_NODE_DEP (node);
  rtx_insn *pro = DEP_PRO (dep);
  rtx_insn *con = DEP_CON (dep);

  if (dep_spec_p (dep))
    move_dep_link (DEP_NODE_BACK (node), INSN_RESOLVED_BACK_DEPS (con),
		   INSN_SPEC_BACK_DEPS (con));
  else
    move_dep_link (DEP_NODE_BACK (node), INSN_RESOLVED_BACK_DEPS (con),
		   INSN_HARD_BACK_DEPS (con));

  move_dep_link (DEP_NODE_FORW (node), INSN_RESOLVED_FORW_DEPS (pro),
		 INSN_FORW_DEPS (pro));
}

/* Make TO depend on all the FROM's producers.
   If RESOLVED_P is true add dependencies to the resolved lists.  */
void
sd_copy_back_deps (rtx_insn *to, rtx_insn *from, bool resolved_p)
{
  sd_list_types_def list_type;
  sd_iterator_def sd_it;
  dep_t dep;

  list_type = resolved_p ? SD_LIST_RES_BACK : SD_LIST_BACK;

  FOR_EACH_DEP (from, list_type, sd_it, dep)
    {
      dep_def _new_dep, *new_dep = &_new_dep;

      copy_dep (new_dep, dep);
      DEP_CON (new_dep) = to;
      sd_add_dep (new_dep, resolved_p);
    }
}

/* Remove a dependency referred to by SD_IT.
   SD_IT will point to the next dependence after removal.  */
void
sd_delete_dep (sd_iterator_def sd_it)
{
  dep_node_t n = DEP_LINK_NODE (*sd_it.linkp);
  dep_t dep = DEP_NODE_DEP (n);
  rtx_insn *pro = DEP_PRO (dep);
  rtx_insn *con = DEP_CON (dep);
  deps_list_t con_back_deps;
  deps_list_t pro_forw_deps;

  if (true_dependency_cache != NULL)
    {
      int elem_luid = INSN_LUID (pro);
      int insn_luid = INSN_LUID (con);

      bitmap_clear_bit (&true_dependency_cache[insn_luid], elem_luid);
      bitmap_clear_bit (&anti_dependency_cache[insn_luid], elem_luid);
      bitmap_clear_bit (&control_dependency_cache[insn_luid], elem_luid);
      bitmap_clear_bit (&output_dependency_cache[insn_luid], elem_luid);

      if (current_sched_info->flags & DO_SPECULATION)
	bitmap_clear_bit (&spec_dependency_cache[insn_luid], elem_luid);
    }

  get_back_and_forw_lists (dep, sd_it.resolved_p,
			   &con_back_deps, &pro_forw_deps);

  remove_from_deps_list (DEP_NODE_BACK (n), con_back_deps);
  remove_from_deps_list (DEP_NODE_FORW (n), pro_forw_deps);

  delete_dep_node (n);
}

/* Dump size of the lists.  */
#define DUMP_LISTS_SIZE (2)

/* Dump dependencies of the lists.  */
#define DUMP_LISTS_DEPS (4)

/* Dump all information about the lists.  */
#define DUMP_LISTS_ALL (DUMP_LISTS_SIZE | DUMP_LISTS_DEPS)

/* Dump deps_lists of INSN specified by TYPES to DUMP.
   FLAGS is a bit mask specifying what information about the lists needs
   to be printed.
   If FLAGS has the very first bit set, then dump all information about
   the lists and propagate this bit into the callee dump functions.  */
static void
dump_lists (FILE *dump, rtx insn, sd_list_types_def types, int flags)
{
  sd_iterator_def sd_it;
  dep_t dep;
  int all;

  all = (flags & 1);

  if (all)
    flags |= DUMP_LISTS_ALL;

  fprintf (dump, "[");

  if (flags & DUMP_LISTS_SIZE)
    fprintf (dump, "%d; ", sd_lists_size (insn, types));

  if (flags & DUMP_LISTS_DEPS)
    {
      FOR_EACH_DEP (insn, types, sd_it, dep)
	{
	  dump_dep (dump, dep, dump_dep_flags | all);
	  fprintf (dump, " ");
	}
    }
}

/* Dump all information about deps_lists of INSN specified by TYPES
   to STDERR.  */
void
sd_debug_lists (rtx insn, sd_list_types_def types)
{
  dump_lists (stderr, insn, types, 1);
  fprintf (stderr, "\n");
}

/* A wrapper around add_dependence_1, to add a dependence of CON on
   PRO, with type DEP_TYPE.  This function implements special handling
   for REG_DEP_CONTROL dependencies.  For these, we optionally promote
   the type to REG_DEP_ANTI if we can determine that predication is
   impossible; otherwise we add additional true dependencies on the
   INSN_COND_DEPS list of the jump (which PRO must be).  */
void
add_dependence (rtx_insn *con, rtx_insn *pro, enum reg_note dep_type)
{
  if (dep_type == REG_DEP_CONTROL
      && !(current_sched_info->flags & DO_PREDICATION))
    dep_type = REG_DEP_ANTI;

  /* A REG_DEP_CONTROL dependence may be eliminated through predication,
     so we must also make the insn dependent on the setter of the
     condition.  */
  if (dep_type == REG_DEP_CONTROL)
    {
      rtx_insn *real_pro = pro;
      rtx_insn *other = real_insn_for_shadow (real_pro);
      rtx cond;

      if (other != NULL_RTX)
	real_pro = other;
      cond = sched_get_reverse_condition_uncached (real_pro);
      /* Verify that the insn does not use a different value in
	 the condition register than the one that was present at
	 the jump.  */
      if (cond == NULL_RTX)
	dep_type = REG_DEP_ANTI;
      else if (INSN_CACHED_COND (real_pro) == const_true_rtx)
	{
	  HARD_REG_SET uses;
	  CLEAR_HARD_REG_SET (uses);
	  note_uses (&PATTERN (con), record_hard_reg_uses, &uses);
	  if (TEST_HARD_REG_BIT (uses, REGNO (XEXP (cond, 0))))
	    dep_type = REG_DEP_ANTI;
	}
      if (dep_type == REG_DEP_CONTROL)
	{
	  if (sched_verbose >= 5)
	    fprintf (sched_dump, "making DEP_CONTROL for %d\n",
		     INSN_UID (real_pro));
	  add_dependence_list (con, INSN_COND_DEPS (real_pro), 0,
			       REG_DEP_TRUE, false);
	}
    }

  add_dependence_1 (con, pro, dep_type);
}

/* A convenience wrapper to operate on an entire list.  HARD should be
   true if DEP_NONREG should be set on newly created dependencies.  */

static void
add_dependence_list (rtx_insn *insn, rtx_insn_list *list, int uncond,
		     enum reg_note dep_type, bool hard)
{
  mark_as_hard = hard;
  for (; list; list = list->next ())
    {
      if (uncond || ! sched_insns_conditions_mutex_p (insn, list->insn ()))
	add_dependence (insn, list->insn (), dep_type);
    }
  mark_as_hard = false;
}

/* Similar, but free *LISTP at the same time, when the context
   is not readonly.  HARD should be true if DEP_NONREG should be set on
   newly created dependencies.  */

static void
add_dependence_list_and_free (class deps_desc *deps, rtx_insn *insn,
			      rtx_insn_list **listp,
                              int uncond, enum reg_note dep_type, bool hard)
{
  add_dependence_list (insn, *listp, uncond, dep_type, hard);

  /* We don't want to short-circuit dependencies involving debug
     insns, because they may cause actual dependencies to be
     disregarded.  */
  if (deps->readonly || DEBUG_INSN_P (insn))
    return;

  free_INSN_LIST_list (listp);
}

/* Remove all occurrences of INSN from LIST.  Return the number of
   occurrences removed.  */

static int
remove_from_dependence_list (rtx_insn *insn, rtx_insn_list **listp)
{
  int removed = 0;

  while (*listp)
    {
      if ((*listp)->insn () == insn)
        {
          remove_free_INSN_LIST_node (listp);
          removed++;
          continue;
        }

      listp = (rtx_insn_list **)&XEXP (*listp, 1);
    }

  return removed;
}

/* Same as above, but process two lists at once.  */
static int
remove_from_both_dependence_lists (rtx_insn *insn,
				   rtx_insn_list **listp,
				   rtx_expr_list **exprp)
{
  int removed = 0;

  while (*listp)
    {
      if (XEXP (*listp, 0) == insn)
        {
          remove_free_INSN_LIST_node (listp);
          remove_free_EXPR_LIST_node (exprp);
          removed++;
          continue;
        }

      listp = (rtx_insn_list **)&XEXP (*listp, 1);
      exprp = (rtx_expr_list **)&XEXP (*exprp, 1);
    }

  return removed;
}

/* Clear all dependencies for an insn.  */
static void
delete_all_dependences (rtx_insn *insn)
{
  sd_iterator_def sd_it;
  dep_t dep;

  /* The below cycle can be optimized to clear the caches and back_deps
     in one call but that would provoke duplication of code from
     delete_dep ().  */

  for (sd_it = sd_iterator_start (insn, SD_LIST_BACK);
       sd_iterator_cond (&sd_it, &dep);)
    sd_delete_dep (sd_it);
}

/* All insns in a scheduling group except the first should only have
   dependencies on the previous insn in the group.  So we find the
   first instruction in the scheduling group by walking the dependence
   chains backwards. Then we add the dependencies for the group to
   the previous nonnote insn.  */

static void
chain_to_prev_insn (rtx_insn *insn)
{
  sd_iterator_def sd_it;
  dep_t dep;
  rtx_insn *prev_nonnote;

  FOR_EACH_DEP (insn, SD_LIST_BACK, sd_it, dep)
    {
      rtx_insn *i = insn;
      rtx_insn *pro = DEP_PRO (dep);

      do
	{
	  i = prev_nonnote_insn (i);

	  if (pro == i)
	    goto next_link;
	} while (SCHED_GROUP_P (i) || DEBUG_INSN_P (i));

      if (! sched_insns_conditions_mutex_p (i, pro))
	add_dependence (i, pro, DEP_TYPE (dep));
    next_link:;
    }

  delete_all_dependences (insn);

  prev_nonnote = prev_nonnote_nondebug_insn (insn);
  if (BLOCK_FOR_INSN (insn) == BLOCK_FOR_INSN (prev_nonnote)
      && ! sched_insns_conditions_mutex_p (insn, prev_nonnote))
    add_dependence (insn, prev_nonnote, REG_DEP_ANTI);
}

/* Process an insn's memory dependencies.  There are four kinds of
   dependencies:

   (0) read dependence: read follows read
   (1) true dependence: read follows write
   (2) output dependence: write follows write
   (3) anti dependence: write follows read

   We are careful to build only dependencies which actually exist, and
   use transitivity to avoid building too many links.  */

/* Add an INSN and MEM reference pair to a pending INSN_LIST and MEM_LIST.
   The MEM is a memory reference contained within INSN, which we are saving
   so that we can do memory aliasing on it.  */

static void
add_insn_mem_dependence (class deps_desc *deps, bool read_p,
			 rtx_insn *insn, rtx mem)
{
  rtx_insn_list **insn_list;
  rtx_insn_list *insn_node;
  rtx_expr_list **mem_list;
  rtx_expr_list *mem_node;

  gcc_assert (!deps->readonly);
  if (read_p)
    {
      insn_list = &deps->pending_read_insns;
      mem_list = &deps->pending_read_mems;
      if (!DEBUG_INSN_P (insn))
	deps->pending_read_list_length++;
    }
  else
    {
      insn_list = &deps->pending_write_insns;
      mem_list = &deps->pending_write_mems;
      deps->pending_write_list_length++;
    }

  insn_node = alloc_INSN_LIST (insn, *insn_list);
  *insn_list = insn_node;

  if (sched_deps_info->use_cselib && MEM_P (mem))
    {
      mem = shallow_copy_rtx (mem);
      XEXP (mem, 0) = cselib_subst_to_values_from_insn (XEXP (mem, 0),
							GET_MODE (mem), insn);
    }
  mem_node = alloc_EXPR_LIST (VOIDmode, canon_rtx (mem), *mem_list);
  *mem_list = mem_node;
}

/* Make a dependency between every memory reference on the pending lists
   and INSN, thus flushing the pending lists.  FOR_READ is true if emitting
   dependencies for a read operation, similarly with FOR_WRITE.  */

static void
flush_pending_lists (class deps_desc *deps, rtx_insn *insn, int for_read,
		     int for_write)
{
  if (for_write)
    {
      add_dependence_list_and_free (deps, insn, &deps->pending_read_insns,
                                    1, REG_DEP_ANTI, true);
      if (!deps->readonly)
        {
          free_EXPR_LIST_list (&deps->pending_read_mems);
          deps->pending_read_list_length = 0;
        }
    }

  add_dependence_list_and_free (deps, insn, &deps->pending_write_insns, 1,
				for_read ? REG_DEP_ANTI : REG_DEP_OUTPUT,
				true);

  add_dependence_list_and_free (deps, insn,
                                &deps->last_pending_memory_flush, 1,
                                for_read ? REG_DEP_ANTI : REG_DEP_OUTPUT,
				true);

  add_dependence_list_and_free (deps, insn, &deps->pending_jump_insns, 1,
				REG_DEP_ANTI, true);

  if (DEBUG_INSN_P (insn))
    {
      if (for_write)
	free_INSN_LIST_list (&deps->pending_read_insns);
      free_INSN_LIST_list (&deps->pending_write_insns);
      free_INSN_LIST_list (&deps->last_pending_memory_flush);
      free_INSN_LIST_list (&deps->pending_jump_insns);
    }

  if (!deps->readonly)
    {
      free_EXPR_LIST_list (&deps->pending_write_mems);
      deps->pending_write_list_length = 0;

      deps->last_pending_memory_flush = alloc_INSN_LIST (insn, NULL_RTX);
      deps->pending_flush_length = 1;
    }
  mark_as_hard = false;
}

/* Instruction which dependencies we are analyzing.  */
static rtx_insn *cur_insn = NULL;

/* Implement hooks for haifa scheduler.  */

static void
haifa_start_insn (rtx_insn *insn)
{
  gcc_assert (insn && !cur_insn);

  cur_insn = insn;
}

static void
haifa_finish_insn (void)
{
  cur_insn = NULL;
}

void
haifa_note_reg_set (int regno)
{
  SET_REGNO_REG_SET (reg_pending_sets, regno);
}

void
haifa_note_reg_clobber (int regno)
{
  SET_REGNO_REG_SET (reg_pending_clobbers, regno);
}

void
haifa_note_reg_use (int regno)
{
  SET_REGNO_REG_SET (reg_pending_uses, regno);
}

static void
haifa_note_mem_dep (rtx mem, rtx pending_mem, rtx_insn *pending_insn, ds_t ds)
{
  if (!(ds & SPECULATIVE))
    {
      mem = NULL_RTX;
      pending_mem = NULL_RTX;
    }
  else
    gcc_assert (ds & BEGIN_DATA);

  {
    dep_def _dep, *dep = &_dep;

    init_dep_1 (dep, pending_insn, cur_insn, ds_to_dt (ds),
                current_sched_info->flags & USE_DEPS_LIST ? ds : 0);
    DEP_NONREG (dep) = 1;
    maybe_add_or_update_dep_1 (dep, false, pending_mem, mem);
  }

}

static void
haifa_note_dep (rtx_insn *elem, ds_t ds)
{
  dep_def _dep;
  dep_t dep = &_dep;

  init_dep (dep, elem, cur_insn, ds_to_dt (ds));
  if (mark_as_hard)
    DEP_NONREG (dep) = 1;
  maybe_add_or_update_dep_1 (dep, false, NULL_RTX, NULL_RTX);
}

static void
note_reg_use (int r)
{
  if (sched_deps_info->note_reg_use)
    sched_deps_info->note_reg_use (r);
}

static void
note_reg_set (int r)
{
  if (sched_deps_info->note_reg_set)
    sched_deps_info->note_reg_set (r);
}

static void
note_reg_clobber (int r)
{
  if (sched_deps_info->note_reg_clobber)
    sched_deps_info->note_reg_clobber (r);
}

static void
note_mem_dep (rtx m1, rtx m2, rtx_insn *e, ds_t ds)
{
  if (sched_deps_info->note_mem_dep)
    sched_deps_info->note_mem_dep (m1, m2, e, ds);
}

static void
note_dep (rtx_insn *e, ds_t ds)
{
  if (sched_deps_info->note_dep)
    sched_deps_info->note_dep (e, ds);
}

/* Return corresponding to DS reg_note.  */
enum reg_note
ds_to_dt (ds_t ds)
{
  if (ds & DEP_TRUE)
    return REG_DEP_TRUE;
  else if (ds & DEP_OUTPUT)
    return REG_DEP_OUTPUT;
  else if (ds & DEP_ANTI)
    return REG_DEP_ANTI;
  else
    {
      gcc_assert (ds & DEP_CONTROL);
      return REG_DEP_CONTROL;
    }
}



/* Functions for computation of info needed for register pressure
   sensitive insn scheduling.  */


/* Allocate and return reg_use_data structure for REGNO and INSN.  */
static struct reg_use_data *
create_insn_reg_use (int regno, rtx_insn *insn)
{
  struct reg_use_data *use;

  use = (struct reg_use_data *) xmalloc (sizeof (struct reg_use_data));
  use->regno = regno;
  use->insn = insn;
  use->next_insn_use = INSN_REG_USE_LIST (insn);
  INSN_REG_USE_LIST (insn) = use;
  return use;
}

/* Allocate reg_set_data structure for REGNO and INSN.  */
static void
create_insn_reg_set (int regno, rtx insn)
{
  struct reg_set_data *set;

  set = (struct reg_set_data *) xmalloc (sizeof (struct reg_set_data));
  set->regno = regno;
  set->insn = insn;
  set->next_insn_set = INSN_REG_SET_LIST (insn);
  INSN_REG_SET_LIST (insn) = set;
}

/* Set up insn register uses for INSN and dependency context DEPS.  */
static void
setup_insn_reg_uses (class deps_desc *deps, rtx_insn *insn)
{
  unsigned i;
  reg_set_iterator rsi;
  struct reg_use_data *use, *use2, *next;
  struct deps_reg *reg_last;

  EXECUTE_IF_SET_IN_REG_SET (reg_pending_uses, 0, i, rsi)
    {
      if (i < FIRST_PSEUDO_REGISTER
	  && TEST_HARD_REG_BIT (ira_no_alloc_regs, i))
	continue;

      if (find_regno_note (insn, REG_DEAD, i) == NULL_RTX
	  && ! REGNO_REG_SET_P (reg_pending_sets, i)
	  && ! REGNO_REG_SET_P (reg_pending_clobbers, i))
	/* Ignore use which is not dying.  */
	continue;

      use = create_insn_reg_use (i, insn);
      use->next_regno_use = use;
      reg_last = &deps->reg_last[i];

      /* Create the cycle list of uses.  */
      for (rtx_insn_list *list = reg_last->uses; list; list = list->next ())
	{
	  use2 = create_insn_reg_use (i, list->insn ());
	  next = use->next_regno_use;
	  use->next_regno_use = use2;
	  use2->next_regno_use = next;
	}
    }
}

/* Register pressure info for the currently processed insn.  */
static struct reg_pressure_data reg_pressure_info[N_REG_CLASSES];

/* Return TRUE if INSN has the use structure for REGNO.  */
static bool
insn_use_p (rtx insn, int regno)
{
  struct reg_use_data *use;

  for (use = INSN_REG_USE_LIST (insn); use != NULL; use = use->next_insn_use)
    if (use->regno == regno)
      return true;
  return false;
}

/* Update the register pressure info after birth of pseudo register REGNO
   in INSN.  Arguments CLOBBER_P and UNUSED_P say correspondingly that
   the register is in clobber or unused after the insn.  */
static void
mark_insn_pseudo_birth (rtx insn, int regno, bool clobber_p, bool unused_p)
{
  int incr, new_incr;
  enum reg_class cl;

  gcc_assert (regno >= FIRST_PSEUDO_REGISTER);
  cl = sched_regno_pressure_class[regno];
  if (cl != NO_REGS)
    {
      incr = ira_reg_class_max_nregs[cl][PSEUDO_REGNO_MODE (regno)];
      if (clobber_p)
	{
	  new_incr = reg_pressure_info[cl].clobber_increase + incr;
	  reg_pressure_info[cl].clobber_increase = new_incr;
	}
      else if (unused_p)
	{
	  new_incr = reg_pressure_info[cl].unused_set_increase + incr;
	  reg_pressure_info[cl].unused_set_increase = new_incr;
	}
      else
	{
	  new_incr = reg_pressure_info[cl].set_increase + incr;
	  reg_pressure_info[cl].set_increase = new_incr;
	  if (! insn_use_p (insn, regno))
	    reg_pressure_info[cl].change += incr;
	  create_insn_reg_set (regno, insn);
	}
      gcc_assert (new_incr < (1 << INCREASE_BITS));
    }
}

/* Like mark_insn_pseudo_regno_birth except that NREGS saying how many
   hard registers involved in the birth.  */
static void
mark_insn_hard_regno_birth (rtx insn, int regno, int nregs,
			    bool clobber_p, bool unused_p)
{
  enum reg_class cl;
  int new_incr, last = regno + nregs;

  while (regno < last)
    {
      gcc_assert (regno < FIRST_PSEUDO_REGISTER);
      if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno))
	{
	  cl = sched_regno_pressure_class[regno];
	  if (cl != NO_REGS)
	    {
	      if (clobber_p)
		{
		  new_incr = reg_pressure_info[cl].clobber_increase + 1;
		  reg_pressure_info[cl].clobber_increase = new_incr;
		}
	      else if (unused_p)
		{
		  new_incr = reg_pressure_info[cl].unused_set_increase + 1;
		  reg_pressure_info[cl].unused_set_increase = new_incr;
		}
	      else
		{
		  new_incr = reg_pressure_info[cl].set_increase + 1;
		  reg_pressure_info[cl].set_increase = new_incr;
		  if (! insn_use_p (insn, regno))
		    reg_pressure_info[cl].change += 1;
		  create_insn_reg_set (regno, insn);
		}
	      gcc_assert (new_incr < (1 << INCREASE_BITS));
	    }
	}
      regno++;
    }
}

/* Update the register pressure info after birth of pseudo or hard
   register REG in INSN.  Arguments CLOBBER_P and UNUSED_P say
   correspondingly that the register is in clobber or unused after the
   insn.  */
static void
mark_insn_reg_birth (rtx insn, rtx reg, bool clobber_p, bool unused_p)
{
  int regno;

  if (GET_CODE (reg) == SUBREG)
    reg = SUBREG_REG (reg);

  if (! REG_P (reg))
    return;

  regno = REGNO (reg);
  if (regno < FIRST_PSEUDO_REGISTER)
    mark_insn_hard_regno_birth (insn, regno, REG_NREGS (reg),
				clobber_p, unused_p);
  else
    mark_insn_pseudo_birth (insn, regno, clobber_p, unused_p);
}

/* Update the register pressure info after death of pseudo register
   REGNO.  */
static void
mark_pseudo_death (int regno)
{
  int incr;
  enum reg_class cl;

  gcc_assert (regno >= FIRST_PSEUDO_REGISTER);
  cl = sched_regno_pressure_class[regno];
  if (cl != NO_REGS)
    {
      incr = ira_reg_class_max_nregs[cl][PSEUDO_REGNO_MODE (regno)];
      reg_pressure_info[cl].change -= incr;
    }
}

/* Like mark_pseudo_death except that NREGS saying how many hard
   registers involved in the death.  */
static void
mark_hard_regno_death (int regno, int nregs)
{
  enum reg_class cl;
  int last = regno + nregs;

  while (regno < last)
    {
      gcc_assert (regno < FIRST_PSEUDO_REGISTER);
      if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno))
	{
	  cl = sched_regno_pressure_class[regno];
	  if (cl != NO_REGS)
	    reg_pressure_info[cl].change -= 1;
	}
      regno++;
    }
}

/* Update the register pressure info after death of pseudo or hard
   register REG.  */
static void
mark_reg_death (rtx reg)
{
  int regno;

  if (GET_CODE (reg) == SUBREG)
    reg = SUBREG_REG (reg);

  if (! REG_P (reg))
    return;

  regno = REGNO (reg);
  if (regno < FIRST_PSEUDO_REGISTER)
    mark_hard_regno_death (regno, REG_NREGS (reg));
  else
    mark_pseudo_death (regno);
}

/* Process SETTER of REG.  DATA is an insn containing the setter.  */
static void
mark_insn_reg_store (rtx reg, const_rtx setter, void *data)
{
  if (setter != NULL_RTX && GET_CODE (setter) != SET)
    return;
  mark_insn_reg_birth
    ((rtx) data, reg, false,
     find_reg_note ((const_rtx) data, REG_UNUSED, reg) != NULL_RTX);
}

/* Like mark_insn_reg_store except notice just CLOBBERs; ignore SETs.  */
static void
mark_insn_reg_clobber (rtx reg, const_rtx setter, void *data)
{
  if (GET_CODE (setter) == CLOBBER)
    mark_insn_reg_birth ((rtx) data, reg, true, false);
}

/* Set up reg pressure info related to INSN.  */
void
init_insn_reg_pressure_info (rtx_insn *insn)
{
  int i, len;
  enum reg_class cl;
  static struct reg_pressure_data *pressure_info;
  rtx link;

  gcc_assert (sched_pressure != SCHED_PRESSURE_NONE);

  if (! INSN_P (insn))
    return;

  for (i = 0; i < ira_pressure_classes_num; i++)
    {
      cl = ira_pressure_classes[i];
      reg_pressure_info[cl].clobber_increase = 0;
      reg_pressure_info[cl].set_increase = 0;
      reg_pressure_info[cl].unused_set_increase = 0;
      reg_pressure_info[cl].change = 0;
    }

  note_stores (insn, mark_insn_reg_clobber, insn);

  note_stores (insn, mark_insn_reg_store, insn);

  if (AUTO_INC_DEC)
    for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
      if (REG_NOTE_KIND (link) == REG_INC)
	mark_insn_reg_store (XEXP (link, 0), NULL_RTX, insn);

  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
    if (REG_NOTE_KIND (link) == REG_DEAD)
      mark_reg_death (XEXP (link, 0));

  len = sizeof (struct reg_pressure_data) * ira_pressure_classes_num;
  pressure_info
    = INSN_REG_PRESSURE (insn) = (struct reg_pressure_data *) xmalloc (len);
  if (sched_pressure == SCHED_PRESSURE_WEIGHTED)
    INSN_MAX_REG_PRESSURE (insn) = (int *) xcalloc (ira_pressure_classes_num
						    * sizeof (int), 1);
  for (i = 0; i < ira_pressure_classes_num; i++)
    {
      cl = ira_pressure_classes[i];
      pressure_info[i].clobber_increase
	= reg_pressure_info[cl].clobber_increase;
      pressure_info[i].set_increase = reg_pressure_info[cl].set_increase;
      pressure_info[i].unused_set_increase
	= reg_pressure_info[cl].unused_set_increase;
      pressure_info[i].change = reg_pressure_info[cl].change;
    }
}




/* Internal variable for sched_analyze_[12] () functions.
   If it is nonzero, this means that sched_analyze_[12] looks
   at the most toplevel SET.  */
static bool can_start_lhs_rhs_p;

/* Extend reg info for the deps context DEPS given that
   we have just generated a register numbered REGNO.  */
static void
extend_deps_reg_info (class deps_desc *deps, int regno)
{
  int max_regno = regno + 1;

  gcc_assert (!reload_completed);

  /* In a readonly context, it would not hurt to extend info,
     but it should not be needed.  */
  if (reload_completed && deps->readonly)
    {
      deps->max_reg = max_regno;
      return;
    }

  if (max_regno > deps->max_reg)
    {
      deps->reg_last = XRESIZEVEC (struct deps_reg, deps->reg_last,
                                   max_regno);
      memset (&deps->reg_last[deps->max_reg],
              0, (max_regno - deps->max_reg)
              * sizeof (struct deps_reg));
      deps->max_reg = max_regno;
    }
}

/* Extends REG_INFO_P if needed.  */
void
maybe_extend_reg_info_p (void)
{
  /* Extend REG_INFO_P, if needed.  */
  if ((unsigned int)max_regno - 1 >= reg_info_p_size)
    {
      size_t new_reg_info_p_size = max_regno + 128;

      gcc_assert (!reload_completed && sel_sched_p ());

      reg_info_p = (struct reg_info_t *) xrecalloc (reg_info_p,
                                                    new_reg_info_p_size,
                                                    reg_info_p_size,
                                                    sizeof (*reg_info_p));
      reg_info_p_size = new_reg_info_p_size;
    }
}

/* Analyze a single reference to register (reg:MODE REGNO) in INSN.
   The type of the reference is specified by REF and can be SET,
   CLOBBER, PRE_DEC, POST_DEC, PRE_INC, POST_INC or USE.  */

static void
sched_analyze_reg (class deps_desc *deps, int regno, machine_mode mode,
		   enum rtx_code ref, rtx_insn *insn)
{
  /* We could emit new pseudos in renaming.  Extend the reg structures.  */
  if (!reload_completed && sel_sched_p ()
      && (regno >= max_reg_num () - 1 || regno >= deps->max_reg))
    extend_deps_reg_info (deps, regno);

  maybe_extend_reg_info_p ();

  /* A hard reg in a wide mode may really be multiple registers.
     If so, mark all of them just like the first.  */
  if (regno < FIRST_PSEUDO_REGISTER)
    {
      int i = hard_regno_nregs (regno, mode);
      if (ref == SET)
	{
	  while (--i >= 0)
	    note_reg_set (regno + i);
	}
      else if (ref == USE)
	{
	  while (--i >= 0)
	    note_reg_use (regno + i);
	}
      else
	{
	  while (--i >= 0)
	    note_reg_clobber (regno + i);
	}
    }

  /* ??? Reload sometimes emits USEs and CLOBBERs of pseudos that
     it does not reload.  Ignore these as they have served their
     purpose already.  */
  else if (regno >= deps->max_reg)
    {
      enum rtx_code code = GET_CODE (PATTERN (insn));
      gcc_assert (code == USE || code == CLOBBER);
    }

  else
    {
      if (ref == SET)
	note_reg_set (regno);
      else if (ref == USE)
	note_reg_use (regno);
      else
	note_reg_clobber (regno);

      /* Pseudos that are REG_EQUIV to something may be replaced
	 by that during reloading.  We need only add dependencies for
	the address in the REG_EQUIV note.  */
      if (!reload_completed && get_reg_known_equiv_p (regno))
	{
	  rtx t = get_reg_known_value (regno);
	  if (MEM_P (t))
	    sched_analyze_2 (deps, XEXP (t, 0), insn);
	}

      /* Don't let it cross a call after scheduling if it doesn't
	 already cross one.  */
      if (REG_N_CALLS_CROSSED (regno) == 0)
	{
	  if (!deps->readonly && ref == USE && !DEBUG_INSN_P (insn))
	    deps->sched_before_next_call
	      = alloc_INSN_LIST (insn, deps->sched_before_next_call);
	  else
	    add_dependence_list (insn, deps->last_function_call, 1,
				 REG_DEP_ANTI, false);
	}
    }
}

/* Analyze a single SET, CLOBBER, PRE_DEC, POST_DEC, PRE_INC or POST_INC
   rtx, X, creating all dependencies generated by the write to the
   destination of X, and reads of everything mentioned.  */

static void
sched_analyze_1 (class deps_desc *deps, rtx x, rtx_insn *insn)
{
  rtx dest = XEXP (x, 0);
  enum rtx_code code = GET_CODE (x);
  bool cslr_p = can_start_lhs_rhs_p;

  can_start_lhs_rhs_p = false;

  gcc_assert (dest);
  if (dest == 0)
    return;

  if (cslr_p && sched_deps_info->start_lhs)
    sched_deps_info->start_lhs (dest);

  if (GET_CODE (dest) == PARALLEL)
    {
      int i;

      for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
	if (XEXP (XVECEXP (dest, 0, i), 0) != 0)
	  sched_analyze_1 (deps,
			   gen_rtx_CLOBBER (VOIDmode,
					    XEXP (XVECEXP (dest, 0, i), 0)),
			   insn);

      if (cslr_p && sched_deps_info->finish_lhs)
	sched_deps_info->finish_lhs ();

      if (code == SET)
	{
	  can_start_lhs_rhs_p = cslr_p;

	  sched_analyze_2 (deps, SET_SRC (x), insn);

	  can_start_lhs_rhs_p = false;
	}

      return;
    }

  while (GET_CODE (dest) == STRICT_LOW_PART || GET_CODE (dest) == SUBREG
	 || GET_CODE (dest) == ZERO_EXTRACT)
    {
      if (GET_CODE (dest) == STRICT_LOW_PART
	 || GET_CODE (dest) == ZERO_EXTRACT
	 || read_modify_subreg_p (dest))
        {
	  /* These both read and modify the result.  We must handle
             them as writes to get proper dependencies for following
             instructions.  We must handle them as reads to get proper
             dependencies from this to previous instructions.
             Thus we need to call sched_analyze_2.  */

	  sched_analyze_2 (deps, XEXP (dest, 0), insn);
	}
      if (GET_CODE (dest) == ZERO_EXTRACT)
	{
	  /* The second and third arguments are values read by this insn.  */
	  sched_analyze_2 (deps, XEXP (dest, 1), insn);
	  sched_analyze_2 (deps, XEXP (dest, 2), insn);
	}
      dest = XEXP (dest, 0);
    }

  if (REG_P (dest))
    {
      int regno = REGNO (dest);
      machine_mode mode = GET_MODE (dest);

      sched_analyze_reg (deps, regno, mode, code, insn);

#ifdef STACK_REGS
      /* Treat all writes to a stack register as modifying the TOS.  */
      if (regno >= FIRST_STACK_REG && regno <= LAST_STACK_REG)
	{
	  /* Avoid analyzing the same register twice.  */
	  if (regno != FIRST_STACK_REG)
	    sched_analyze_reg (deps, FIRST_STACK_REG, mode, code, insn);

	  add_to_hard_reg_set (&implicit_reg_pending_uses, mode,
			       FIRST_STACK_REG);
	}
#endif
      if (!deps->readonly && regno == STACK_POINTER_REGNUM)
	{
	  /* Please see PR114115.  We have insn modifying memory on the stack
	     and not addressed by stack pointer and we have insn reserving the
	     stack space.  If we move the insn modifying memory before insn
	     reserving the stack space, we can change memory out of the red
	     zone.  Even worse, some optimizations (e.g. peephole) can add
	     insns using temporary stack slots before insn reserving the stack
	     space but after the insn modifying memory.  This will corrupt the
	     modified memory.  Therefore we treat insn changing the stack as
	     reading unknown memory.  This will create anti-dependence.  We
	     don't need to treat the insn as writing memory because GCC by
	     itself does not generate code reading undefined stack memory.  */
	  if ((deps->pending_read_list_length + deps->pending_write_list_length)
	      >= param_max_pending_list_length
	      && !DEBUG_INSN_P (insn))
	    flush_pending_lists (deps, insn, true, true);
	  add_insn_mem_dependence (deps, true, insn, dest);
	}
    }
  else if (MEM_P (dest))
    {
      /* Writing memory.  */
      rtx t = dest;

      if (sched_deps_info->use_cselib)
	{
	  machine_mode address_mode = get_address_mode (dest);

	  t = shallow_copy_rtx (dest);
	  cselib_lookup_from_insn (XEXP (t, 0), address_mode, 1,
				   GET_MODE (t), insn);
	  XEXP (t, 0)
	    = cselib_subst_to_values_from_insn (XEXP (t, 0), GET_MODE (t),
						insn);
	}
      t = canon_rtx (t);

      /* Pending lists can't get larger with a readonly context.  */
      if (!deps->readonly
          && ((deps->pending_read_list_length + deps->pending_write_list_length)
	      >= param_max_pending_list_length))
	{
	  /* Flush all pending reads and writes to prevent the pending lists
	     from getting any larger.  Insn scheduling runs too slowly when
	     these lists get long.  When compiling GCC with itself,
	     this flush occurs 8 times for sparc, and 10 times for m88k using
	     the default value of 32.  */
	  flush_pending_lists (deps, insn, false, true);
	}
      else
	{
	  rtx_insn_list *pending;
	  rtx_expr_list *pending_mem;

	  pending = deps->pending_read_insns;
	  pending_mem = deps->pending_read_mems;
	  while (pending)
	    {
	      rtx mem = pending_mem->element ();
	      if (REG_P (mem)
		  || (anti_dependence (mem, t)
		      && ! sched_insns_conditions_mutex_p (insn, pending->insn ())))
		note_mem_dep (t, mem, pending->insn (), DEP_ANTI);

	      pending = pending->next ();
	      pending_mem = pending_mem->next ();
	    }

	  pending = deps->pending_write_insns;
	  pending_mem = deps->pending_write_mems;
	  while (pending)
	    {
	      if (output_dependence (pending_mem->element (), t)
		  && ! sched_insns_conditions_mutex_p (insn, pending->insn ()))
		note_mem_dep (t, pending_mem->element (),
			      pending->insn (),
			      DEP_OUTPUT);

	      pending = pending->next ();
	      pending_mem = pending_mem-> next ();
	    }

	  add_dependence_list (insn, deps->last_pending_memory_flush, 1,
			       REG_DEP_ANTI, true);
	  add_dependence_list (insn, deps->pending_jump_insns, 1,
			       REG_DEP_CONTROL, true);

          if (!deps->readonly)
            add_insn_mem_dependence (deps, false, insn, dest);
	}
      sched_analyze_2 (deps, XEXP (dest, 0), insn);
    }

  if (cslr_p && sched_deps_info->finish_lhs)
    sched_deps_info->finish_lhs ();

  /* Analyze reads.  */
  if (GET_CODE (x) == SET)
    {
      can_start_lhs_rhs_p = cslr_p;

      sched_analyze_2 (deps, SET_SRC (x), insn);

      can_start_lhs_rhs_p = false;
    }
}

/* Analyze the uses of memory and registers in rtx X in INSN.  */
static void
sched_analyze_2 (class deps_desc *deps, rtx x, rtx_insn *insn)
{
  int i;
  int j;
  enum rtx_code code;
  const char *fmt;
  bool cslr_p = can_start_lhs_rhs_p;

  can_start_lhs_rhs_p = false;

  gcc_assert (x);
  if (x == 0)
    return;

  if (cslr_p && sched_deps_info->start_rhs)
    sched_deps_info->start_rhs (x);

  code = GET_CODE (x);

  switch (code)
    {
    CASE_CONST_ANY:
    case SYMBOL_REF:
    case CONST:
    case LABEL_REF:
      /* Ignore constants.  */
      if (cslr_p && sched_deps_info->finish_rhs)
	sched_deps_info->finish_rhs ();

      return;

    case REG:
      {
	int regno = REGNO (x);
	machine_mode mode = GET_MODE (x);

	sched_analyze_reg (deps, regno, mode, USE, insn);

#ifdef STACK_REGS
      /* Treat all reads of a stack register as modifying the TOS.  */
      if (regno >= FIRST_STACK_REG && regno <= LAST_STACK_REG)
	{
	  /* Avoid analyzing the same register twice.  */
	  if (regno != FIRST_STACK_REG)
	    sched_analyze_reg (deps, FIRST_STACK_REG, mode, USE, insn);
	  sched_analyze_reg (deps, FIRST_STACK_REG, mode, SET, insn);
	}
#endif

	if (cslr_p && sched_deps_info->finish_rhs)
	  sched_deps_info->finish_rhs ();

	return;
      }

    case MEM:
      {
	if (DEBUG_INSN_P (insn) && sched_deps_info->use_cselib)
	  {
	    machine_mode address_mode = get_address_mode (x);

	    cselib_lookup_from_insn (XEXP (x, 0), address_mode, 1,
				     GET_MODE (x), insn);
	  }
	else if (!DEBUG_INSN_P (insn))
	  {
	    /* Reading memory.  */
	    rtx_insn_list *u;
	    rtx_insn_list *pending;
	    rtx_expr_list *pending_mem;
	    rtx t = x;

	    if (sched_deps_info->use_cselib)
	      {
		machine_mode address_mode = get_address_mode (t);

		t = shallow_copy_rtx (t);
		cselib_lookup_from_insn (XEXP (t, 0), address_mode, 1,
					 GET_MODE (t), insn);
		XEXP (t, 0)
		  = cselib_subst_to_values_from_insn (XEXP (t, 0), GET_MODE (t),
						      insn);
	      }

	    t = canon_rtx (t);
	    pending = deps->pending_read_insns;
	    pending_mem = deps->pending_read_mems;
	    while (pending)
	      {
		rtx mem = pending_mem->element ();
		if (MEM_P (mem) && read_dependence (mem, t)
		    && ! sched_insns_conditions_mutex_p (insn, pending->insn ()))
		  note_mem_dep (t, mem, pending->insn (), DEP_ANTI);

		pending = pending->next ();
		pending_mem = pending_mem->next ();
	      }

	    pending = deps->pending_write_insns;
	    pending_mem = deps->pending_write_mems;
	    while (pending)
	      {
		if (true_dependence (pending_mem->element (), VOIDmode, t)
		    && ! sched_insns_conditions_mutex_p (insn,
							 pending->insn ()))
		  note_mem_dep (t, pending_mem->element (),
				pending->insn (),
				sched_deps_info->generate_spec_deps
				? BEGIN_DATA | DEP_TRUE : DEP_TRUE);

		pending = pending->next ();
		pending_mem = pending_mem->next ();
	      }

	    for (u = deps->last_pending_memory_flush; u; u = u->next ())
	      add_dependence (insn, u->insn (), REG_DEP_ANTI);

	    for (u = deps->pending_jump_insns; u; u = u->next ())
	      if (deps_may_trap_p (x))
		{
		  if ((sched_deps_info->generate_spec_deps)
		      && sel_sched_p () && (spec_info->mask & BEGIN_CONTROL))
		    {
		      ds_t ds = set_dep_weak (DEP_ANTI, BEGIN_CONTROL,
					      MAX_DEP_WEAK);

		      note_dep (u->insn (), ds);
		    }
		  else
		    add_dependence (insn, u->insn (), REG_DEP_CONTROL);
		}
	  }

	/* Always add these dependencies to pending_reads, since
	   this insn may be followed by a write.  */
	if (!deps->readonly)
	  {
	    if ((deps->pending_read_list_length
		 + deps->pending_write_list_length)
		>= param_max_pending_list_length
		&& !DEBUG_INSN_P (insn))
	      flush_pending_lists (deps, insn, true, true);
	    add_insn_mem_dependence (deps, true, insn, x);
	  }

	sched_analyze_2 (deps, XEXP (x, 0), insn);

	if (cslr_p && sched_deps_info->finish_rhs)
	  sched_deps_info->finish_rhs ();

	return;
      }

    /* Force pending stores to memory in case a trap handler needs them.
       Also force pending loads from memory; loads and stores can segfault
       and the signal handler won't be triggered if the trap insn was moved
       above load or store insn.  */
    case TRAP_IF:
      flush_pending_lists (deps, insn, true, true);
      break;

    case PREFETCH:
      if (PREFETCH_SCHEDULE_BARRIER_P (x))
	reg_pending_barrier = TRUE_BARRIER;
      /* Prefetch insn contains addresses only.  So if the prefetch
	 address has no registers, there will be no dependencies on
	 the prefetch insn.  This is wrong with result code
	 correctness point of view as such prefetch can be moved below
	 a jump insn which usually generates MOVE_BARRIER preventing
	 to move insns containing registers or memories through the
	 barrier.  It is also wrong with generated code performance
	 point of view as prefetch withouth dependecies will have a
	 tendency to be issued later instead of earlier.  It is hard
	 to generate accurate dependencies for prefetch insns as
	 prefetch has only the start address but it is better to have
	 something than nothing.  */
      if (!deps->readonly)
	{
	  rtx x = gen_rtx_MEM (Pmode, XEXP (PATTERN (insn), 0));
	  if (sched_deps_info->use_cselib)
	    cselib_lookup_from_insn (x, Pmode, true, VOIDmode, insn);
	  add_insn_mem_dependence (deps, true, insn, x);
	}
      break;

    case UNSPEC_VOLATILE:
      flush_pending_lists (deps, insn, true, true);
      /* FALLTHRU */

    case ASM_OPERANDS:
    case ASM_INPUT:
      {
	/* Traditional and volatile asm instructions must be considered to use
	   and clobber all hard registers, all pseudo-registers and all of
	   memory.  So must TRAP_IF and UNSPEC_VOLATILE operations.

	   Consider for instance a volatile asm that changes the fpu rounding
	   mode.  An insn should not be moved across this even if it only uses
	   pseudo-regs because it might give an incorrectly rounded result.  */
	if ((code != ASM_OPERANDS || MEM_VOLATILE_P (x))
	    && !DEBUG_INSN_P (insn))
	  reg_pending_barrier = TRUE_BARRIER;

	/* For all ASM_OPERANDS, we must traverse the vector of input operands.
	   We cannot just fall through here since then we would be confused
	   by the ASM_INPUT rtx inside ASM_OPERANDS, which do not indicate
	   traditional asms unlike their normal usage.  */

	if (code == ASM_OPERANDS)
	  {
	    for (j = 0; j < ASM_OPERANDS_INPUT_LENGTH (x); j++)
	      sched_analyze_2 (deps, ASM_OPERANDS_INPUT (x, j), insn);

	    if (cslr_p && sched_deps_info->finish_rhs)
	      sched_deps_info->finish_rhs ();

	    return;
	  }
	break;
      }

    case PRE_DEC:
    case POST_DEC:
    case PRE_INC:
    case POST_INC:
      /* These both read and modify the result.  We must handle them as writes
         to get proper dependencies for following instructions.  We must handle
         them as reads to get proper dependencies from this to previous
         instructions.  Thus we need to pass them to both sched_analyze_1
         and sched_analyze_2.  We must call sched_analyze_2 first in order
         to get the proper antecedent for the read.  */
      sched_analyze_2 (deps, XEXP (x, 0), insn);
      sched_analyze_1 (deps, x, insn);

      if (cslr_p && sched_deps_info->finish_rhs)
	sched_deps_info->finish_rhs ();

      return;

    case POST_MODIFY:
    case PRE_MODIFY:
      /* op0 = op0 + op1 */
      sched_analyze_2 (deps, XEXP (x, 0), insn);
      sched_analyze_2 (deps, XEXP (x, 1), insn);
      sched_analyze_1 (deps, x, insn);

      if (cslr_p && sched_deps_info->finish_rhs)
	sched_deps_info->finish_rhs ();

      return;

    default:
      break;
    }

  /* Other cases: walk the insn.  */
  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'e')
	sched_analyze_2 (deps, XEXP (x, i), insn);
      else if (fmt[i] == 'E')
	for (j = 0; j < XVECLEN (x, i); j++)
	  sched_analyze_2 (deps, XVECEXP (x, i, j), insn);
    }

  if (cslr_p && sched_deps_info->finish_rhs)
    sched_deps_info->finish_rhs ();
}

/* Try to group two fusible insns together to prevent scheduler
   from scheduling them apart.  */

static void
sched_macro_fuse_insns (rtx_insn *insn)
{
  rtx_insn *prev;
  /* No target hook would return true for debug insn as any of the
     hook operand, and with very large sequences of only debug insns
     where on each we call sched_macro_fuse_insns it has quadratic
     compile time complexity.  */
  if (DEBUG_INSN_P (insn))
    return;
  prev = prev_nonnote_nondebug_insn_bb (insn);
  if (!prev)
    return;

  if (any_condjump_p (insn))
    {
      unsigned int condreg1, condreg2;
      rtx cc_reg_1;
      if (targetm.fixed_condition_code_regs (&condreg1, &condreg2))
	{
	  cc_reg_1 = gen_rtx_REG (CCmode, condreg1);
	  if (reg_referenced_p (cc_reg_1, PATTERN (insn))
	      && modified_in_p (cc_reg_1, prev))
	    {
	      if (targetm.sched.macro_fusion_pair_p (prev, insn))
		SCHED_GROUP_P (insn) = 1;
	      return;
	    }
	}
    }

  if (single_set (insn) && single_set (prev))
    {
      if (targetm.sched.macro_fusion_pair_p (prev, insn))
	SCHED_GROUP_P (insn) = 1;
    }
}

/* Get the implicit reg pending clobbers for INSN and save them in TEMP.  */
void
get_implicit_reg_pending_clobbers (HARD_REG_SET *temp, rtx_insn *insn)
{
  extract_insn (insn);
  preprocess_constraints (insn);
  alternative_mask preferred = get_preferred_alternatives (insn);
  ira_implicitly_set_insn_hard_regs (temp, preferred);
  *temp &= ~ira_no_alloc_regs;
}

/* Analyze an INSN with pattern X to find all dependencies.  */
static void
sched_analyze_insn (class deps_desc *deps, rtx x, rtx_insn *insn)
{
  RTX_CODE code = GET_CODE (x);
  rtx link;
  unsigned i;
  reg_set_iterator rsi;

  if (! reload_completed)
    {
      HARD_REG_SET temp;
      get_implicit_reg_pending_clobbers (&temp, insn);
      implicit_reg_pending_clobbers |= temp;
    }

  can_start_lhs_rhs_p = (NONJUMP_INSN_P (insn)
			 && code == SET);

  /* Group compare and branch insns for macro-fusion.  */
  if (!deps->readonly
      && targetm.sched.macro_fusion_p
      && targetm.sched.macro_fusion_p ())
    sched_macro_fuse_insns (insn);

  if (may_trap_p (x))
    /* Avoid moving trapping instructions across function calls that might
       not always return.  */
    add_dependence_list (insn, deps->last_function_call_may_noreturn,
			 1, REG_DEP_ANTI, true);

  /* We must avoid creating a situation in which two successors of the
     current block have different unwind info after scheduling.  If at any
     point the two paths re-join this leads to incorrect unwind info.  */
  /* ??? There are certain situations involving a forced frame pointer in
     which, with extra effort, we could fix up the unwind info at a later
     CFG join.  However, it seems better to notice these cases earlier
     during prologue generation and avoid marking the frame pointer setup
     as frame-related at all.  */
  if (RTX_FRAME_RELATED_P (insn))
    {
      /* Make sure prologue insn is scheduled before next jump.  */
      deps->sched_before_next_jump
	= alloc_INSN_LIST (insn, deps->sched_before_next_jump);

      /* Make sure epilogue insn is scheduled after preceding jumps.  */
      add_dependence_list (insn, deps->last_pending_memory_flush, 1,
			   REG_DEP_ANTI, true);
      add_dependence_list (insn, deps->pending_jump_insns, 1, REG_DEP_ANTI,
			   true);
    }

  if (code == COND_EXEC)
    {
      sched_analyze_2 (deps, COND_EXEC_TEST (x), insn);

      /* ??? Should be recording conditions so we reduce the number of
	 false dependencies.  */
      x = COND_EXEC_CODE (x);
      code = GET_CODE (x);
    }
  if (code == SET || code == CLOBBER)
    {
      sched_analyze_1 (deps, x, insn);

      /* Bare clobber insns are used for letting life analysis, reg-stack
	 and others know that a value is dead.  Depend on the last call
	 instruction so that reg-stack won't get confused.  */
      if (code == CLOBBER)
	add_dependence_list (insn, deps->last_function_call, 1,
			     REG_DEP_OUTPUT, true);
    }
  else if (code == PARALLEL)
    {
      for (i = XVECLEN (x, 0); i--;)
	{
	  rtx sub = XVECEXP (x, 0, i);
	  code = GET_CODE (sub);

	  if (code == COND_EXEC)
	    {
	      sched_analyze_2 (deps, COND_EXEC_TEST (sub), insn);
	      sub = COND_EXEC_CODE (sub);
	      code = GET_CODE (sub);
	    }
	  else if (code == SET || code == CLOBBER)
	    sched_analyze_1 (deps, sub, insn);
	  else
	    sched_analyze_2 (deps, sub, insn);
	}
    }
  else
    sched_analyze_2 (deps, x, insn);

  /* Mark registers CLOBBERED or used by called function.  */
  if (CALL_P (insn))
    {
      for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
	{
	  if (GET_CODE (XEXP (link, 0)) == CLOBBER)
	    sched_analyze_1 (deps, XEXP (link, 0), insn);
	  else if (GET_CODE (XEXP (link, 0)) != SET)
	    sched_analyze_2 (deps, XEXP (link, 0), insn);
	}
      /* Don't schedule anything after a tail call, tail call needs
	 to use at least all call-saved registers.  */
      if (SIBLING_CALL_P (insn))
	reg_pending_barrier = TRUE_BARRIER;
      else if (find_reg_note (insn, REG_SETJMP, NULL))
	reg_pending_barrier = MOVE_BARRIER;
    }

  if (JUMP_P (insn))
    {
      rtx_insn *next = next_nonnote_nondebug_insn (insn);
      /* ??? For tablejumps, the barrier may appear not immediately after
         the jump, but after a label and a jump_table_data insn.  */
      if (next && LABEL_P (next) && NEXT_INSN (next)
	  && JUMP_TABLE_DATA_P (NEXT_INSN (next)))
	next = NEXT_INSN (NEXT_INSN (next));
      if (next && BARRIER_P (next))
	reg_pending_barrier = MOVE_BARRIER;
      else
	{
	  rtx_insn_list *pending;
	  rtx_expr_list *pending_mem;

          if (sched_deps_info->compute_jump_reg_dependencies)
            {
              (*sched_deps_info->compute_jump_reg_dependencies)
		(insn, reg_pending_control_uses);

              /* Make latency of jump equal to 0 by using anti-dependence.  */
              EXECUTE_IF_SET_IN_REG_SET (reg_pending_control_uses, 0, i, rsi)
                {
                  struct deps_reg *reg_last = &deps->reg_last[i];
                  add_dependence_list (insn, reg_last->sets, 0, REG_DEP_ANTI,
				       false);
                  add_dependence_list (insn, reg_last->implicit_sets,
				       0, REG_DEP_ANTI, false);
                  add_dependence_list (insn, reg_last->clobbers, 0,
				       REG_DEP_ANTI, false);
                }
            }

	  /* All memory writes and volatile reads must happen before the
	     jump.  Non-volatile reads must happen before the jump iff
	     the result is needed by the above register used mask.  */

	  pending = deps->pending_write_insns;
	  pending_mem = deps->pending_write_mems;
	  while (pending)
	    {
	      if (! sched_insns_conditions_mutex_p (insn, pending->insn ()))
		add_dependence (insn, pending->insn (),	REG_DEP_OUTPUT);
	      pending = pending->next ();
	      pending_mem = pending_mem->next ();
	    }

	  pending = deps->pending_read_insns;
	  pending_mem = deps->pending_read_mems;
	  while (pending)
	    {
	      rtx mem = pending_mem->element ();
	      if (MEM_P (mem) && MEM_VOLATILE_P (mem)
		  && ! sched_insns_conditions_mutex_p (insn, pending->insn ()))
		add_dependence (insn, pending->insn (),	REG_DEP_OUTPUT);
	      pending = pending->next ();
	      pending_mem = pending_mem->next ();
	    }

	  add_dependence_list (insn, deps->last_pending_memory_flush, 1,
			       REG_DEP_ANTI, true);
	  add_dependence_list (insn, deps->pending_jump_insns, 1,
			       REG_DEP_ANTI, true);
	}
    }

  /* If this instruction can throw an exception, then moving it changes
     where block boundaries fall.  This is mighty confusing elsewhere.
     Therefore, prevent such an instruction from being moved.  Same for
     non-jump instructions that define block boundaries.
     ??? Unclear whether this is still necessary in EBB mode.  If not,
     add_branch_dependences should be adjusted for RGN mode instead.  */
  if (((CALL_P (insn) || JUMP_P (insn)) && can_throw_internal (insn))
      || (NONJUMP_INSN_P (insn) && control_flow_insn_p (insn)))
    reg_pending_barrier = MOVE_BARRIER;

  if (sched_pressure != SCHED_PRESSURE_NONE)
    {
      setup_insn_reg_uses (deps, insn);
      init_insn_reg_pressure_info (insn);
    }

  /* Add register dependencies for insn.  */
  if (DEBUG_INSN_P (insn))
    {
      rtx_insn *prev = deps->last_debug_insn;
      rtx_insn_list *u;

      if (!deps->readonly)
	deps->last_debug_insn = insn;

      if (prev)
	add_dependence (insn, prev, REG_DEP_ANTI);

      add_dependence_list (insn, deps->last_function_call, 1,
			   REG_DEP_ANTI, false);

      if (!sel_sched_p ())
	for (u = deps->last_pending_memory_flush; u; u = u->next ())
	  add_dependence (insn, u->insn (), REG_DEP_ANTI);

      EXECUTE_IF_SET_IN_REG_SET (reg_pending_uses, 0, i, rsi)
	{
	  struct deps_reg *reg_last = &deps->reg_last[i];
	  add_dependence_list (insn, reg_last->sets, 1, REG_DEP_ANTI, false);
	  /* There's no point in making REG_DEP_CONTROL dependencies for
	     debug insns.  */
	  add_dependence_list (insn, reg_last->clobbers, 1, REG_DEP_ANTI,
			       false);

	  if (!deps->readonly)
	    reg_last->uses = alloc_INSN_LIST (insn, reg_last->uses);
	}
      CLEAR_REG_SET (reg_pending_uses);

      /* Quite often, a debug insn will refer to stuff in the
	 previous instruction, but the reason we want this
	 dependency here is to make sure the scheduler doesn't
	 gratuitously move a debug insn ahead.  This could dirty
	 DF flags and cause additional analysis that wouldn't have
	 occurred in compilation without debug insns, and such
	 additional analysis can modify the generated code.  */
      prev = PREV_INSN (insn);

      if (prev && NONDEBUG_INSN_P (prev))
	add_dependence (insn, prev, REG_DEP_ANTI);
    }
  else
    {
      regset_head set_or_clobbered;

      EXECUTE_IF_SET_IN_REG_SET (reg_pending_uses, 0, i, rsi)
	{
	  struct deps_reg *reg_last = &deps->reg_last[i];
	  add_dependence_list (insn, reg_last->sets, 0, REG_DEP_TRUE, false);
	  add_dependence_list (insn, reg_last->implicit_sets, 0, REG_DEP_ANTI,
			       false);
	  add_dependence_list (insn, reg_last->clobbers, 0, REG_DEP_TRUE,
			       false);

	  if (!deps->readonly)
	    {
	      reg_last->uses = alloc_INSN_LIST (insn, reg_last->uses);
	      reg_last->uses_length++;
	    }
	}

      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
	if (TEST_HARD_REG_BIT (implicit_reg_pending_uses, i))
	  {
	    struct deps_reg *reg_last = &deps->reg_last[i];
	    add_dependence_list (insn, reg_last->sets, 0, REG_DEP_TRUE, false);
	    add_dependence_list (insn, reg_last->implicit_sets, 0,
				 REG_DEP_ANTI, false);
	    add_dependence_list (insn, reg_last->clobbers, 0, REG_DEP_TRUE,
				 false);

	    if (!deps->readonly)
	      {
		reg_last->uses = alloc_INSN_LIST (insn, reg_last->uses);
		reg_last->uses_length++;
	      }
	  }

      if (targetm.sched.exposed_pipeline)
	{
	  INIT_REG_SET (&set_or_clobbered);
	  bitmap_ior (&set_or_clobbered, reg_pending_clobbers,
		      reg_pending_sets);
	  EXECUTE_IF_SET_IN_REG_SET (&set_or_clobbered, 0, i, rsi)
	    {
	      struct deps_reg *reg_last = &deps->reg_last[i];
	      rtx list;
	      for (list = reg_last->uses; list; list = XEXP (list, 1))
		{
		  rtx other = XEXP (list, 0);
		  if (INSN_CACHED_COND (other) != const_true_rtx
		      && refers_to_regno_p (i, INSN_CACHED_COND (other)))
		    INSN_CACHED_COND (other) = const_true_rtx;
		}
	    }
	}

      /* If the current insn is conditional, we can't free any
	 of the lists.  */
      if (sched_has_condition_p (insn))
	{
	  EXECUTE_IF_SET_IN_REG_SET (reg_pending_clobbers, 0, i, rsi)
	    {
	      struct deps_reg *reg_last = &deps->reg_last[i];
	      add_dependence_list (insn, reg_last->sets, 0, REG_DEP_OUTPUT,
				   false);
	      add_dependence_list (insn, reg_last->implicit_sets, 0,
				   REG_DEP_ANTI, false);
	      add_dependence_list (insn, reg_last->uses, 0, REG_DEP_ANTI,
				   false);
	      add_dependence_list (insn, reg_last->control_uses, 0,
				   REG_DEP_CONTROL, false);

	      if (!deps->readonly)
		{
		  reg_last->clobbers
		    = alloc_INSN_LIST (insn, reg_last->clobbers);
		  reg_last->clobbers_length++;
		}
	    }
	  EXECUTE_IF_SET_IN_REG_SET (reg_pending_sets, 0, i, rsi)
	    {
	      struct deps_reg *reg_last = &deps->reg_last[i];
	      add_dependence_list (insn, reg_last->sets, 0, REG_DEP_OUTPUT,
				   false);
	      add_dependence_list (insn, reg_last->implicit_sets, 0,
				   REG_DEP_ANTI, false);
	      add_dependence_list (insn, reg_last->clobbers, 0, REG_DEP_OUTPUT,
				   false);
	      add_dependence_list (insn, reg_last->uses, 0, REG_DEP_ANTI,
				   false);
	      add_dependence_list (insn, reg_last->control_uses, 0,
				   REG_DEP_CONTROL, false);

	      if (!deps->readonly)
		reg_last->sets = alloc_INSN_LIST (insn, reg_last->sets);
	    }
	}
      else
	{
	  EXECUTE_IF_SET_IN_REG_SET (reg_pending_clobbers, 0, i, rsi)
	    {
	      struct deps_reg *reg_last = &deps->reg_last[i];
	      if (reg_last->uses_length >= param_max_pending_list_length
		  || reg_last->clobbers_length >= param_max_pending_list_length)
		{
		  add_dependence_list_and_free (deps, insn, &reg_last->sets, 0,
						REG_DEP_OUTPUT, false);
		  add_dependence_list_and_free (deps, insn,
						&reg_last->implicit_sets, 0,
						REG_DEP_ANTI, false);
		  add_dependence_list_and_free (deps, insn, &reg_last->uses, 0,
						REG_DEP_ANTI, false);
		  add_dependence_list_and_free (deps, insn,
						&reg_last->control_uses, 0,
						REG_DEP_ANTI, false);
		  add_dependence_list_and_free (deps, insn,
						&reg_last->clobbers, 0,
						REG_DEP_OUTPUT, false);

		  if (!deps->readonly)
		    {
		      reg_last->sets = alloc_INSN_LIST (insn, reg_last->sets);
		      reg_last->clobbers_length = 0;
		      reg_last->uses_length = 0;
		    }
		}
	      else
		{
		  add_dependence_list (insn, reg_last->sets, 0, REG_DEP_OUTPUT,
				       false);
		  add_dependence_list (insn, reg_last->implicit_sets, 0,
				       REG_DEP_ANTI, false);
		  add_dependence_list (insn, reg_last->uses, 0, REG_DEP_ANTI,
				       false);
		  add_dependence_list (insn, reg_last->control_uses, 0,
				       REG_DEP_CONTROL, false);
		}

	      if (!deps->readonly)
		{
		  reg_last->clobbers_length++;
		  reg_last->clobbers
		    = alloc_INSN_LIST (insn, reg_last->clobbers);
		}
	    }
	  EXECUTE_IF_SET_IN_REG_SET (reg_pending_sets, 0, i, rsi)
	    {
	      struct deps_reg *reg_last = &deps->reg_last[i];

	      add_dependence_list_and_free (deps, insn, &reg_last->sets, 0,
					    REG_DEP_OUTPUT, false);
	      add_dependence_list_and_free (deps, insn,
					    &reg_last->implicit_sets,
					    0, REG_DEP_ANTI, false);
	      add_dependence_list_and_free (deps, insn, &reg_last->clobbers, 0,
					    REG_DEP_OUTPUT, false);
	      add_dependence_list_and_free (deps, insn, &reg_last->uses, 0,
					    REG_DEP_ANTI, false);
	      add_dependence_list (insn, reg_last->control_uses, 0,
				   REG_DEP_CONTROL, false);

	      if (!deps->readonly)
		{
		  reg_last->sets = alloc_INSN_LIST (insn, reg_last->sets);
		  reg_last->uses_length = 0;
		  reg_last->clobbers_length = 0;
		}
	    }
	}
      if (!deps->readonly)
	{
	  EXECUTE_IF_SET_IN_REG_SET (reg_pending_control_uses, 0, i, rsi)
	    {
	      struct deps_reg *reg_last = &deps->reg_last[i];
	      reg_last->control_uses
		= alloc_INSN_LIST (insn, reg_last->control_uses);
	    }
	}
    }

  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    if (TEST_HARD_REG_BIT (implicit_reg_pending_clobbers, i))
      {
	struct deps_reg *reg_last = &deps->reg_last[i];
	add_dependence_list (insn, reg_last->sets, 0, REG_DEP_ANTI, false);
	add_dependence_list (insn, reg_last->clobbers, 0, REG_DEP_ANTI, false);
	add_dependence_list (insn, reg_last->uses, 0, REG_DEP_ANTI, false);
	add_dependence_list (insn, reg_last->control_uses, 0, REG_DEP_ANTI,
			     false);

	if (!deps->readonly)
	  reg_last->implicit_sets
	    = alloc_INSN_LIST (insn, reg_last->implicit_sets);
      }

  if (!deps->readonly)
    {
      IOR_REG_SET (&deps->reg_last_in_use, reg_pending_uses);
      IOR_REG_SET (&deps->reg_last_in_use, reg_pending_clobbers);
      IOR_REG_SET (&deps->reg_last_in_use, reg_pending_sets);
      IOR_REG_SET_HRS (&deps->reg_last_in_use,
		       implicit_reg_pending_uses
		       | implicit_reg_pending_clobbers);

      /* Set up the pending barrier found.  */
      deps->last_reg_pending_barrier = reg_pending_barrier;
    }

  CLEAR_REG_SET (reg_pending_uses);
  CLEAR_REG_SET (reg_pending_clobbers);
  CLEAR_REG_SET (reg_pending_sets);
  CLEAR_REG_SET (reg_pending_control_uses);
  CLEAR_HARD_REG_SET (implicit_reg_pending_clobbers);
  CLEAR_HARD_REG_SET (implicit_reg_pending_uses);

  /* Add dependencies if a scheduling barrier was found.  */
  if (reg_pending_barrier)
    {
      /* In the case of barrier the most added dependencies are not
         real, so we use anti-dependence here.  */
      if (sched_has_condition_p (insn))
	{
	  EXECUTE_IF_SET_IN_REG_SET (&deps->reg_last_in_use, 0, i, rsi)
	    {
	      struct deps_reg *reg_last = &deps->reg_last[i];
	      add_dependence_list (insn, reg_last->uses, 0, REG_DEP_ANTI,
				   true);
	      add_dependence_list (insn, reg_last->sets, 0,
				   reg_pending_barrier == TRUE_BARRIER
				   ? REG_DEP_TRUE : REG_DEP_ANTI, true);
	      add_dependence_list (insn, reg_last->implicit_sets, 0,
				   REG_DEP_ANTI, true);
	      add_dependence_list (insn, reg_last->clobbers, 0,
				   reg_pending_barrier == TRUE_BARRIER
				   ? REG_DEP_TRUE : REG_DEP_ANTI, true);
	    }
	}
      else
	{
	  EXECUTE_IF_SET_IN_REG_SET (&deps->reg_last_in_use, 0, i, rsi)
	    {
	      struct deps_reg *reg_last = &deps->reg_last[i];
	      add_dependence_list_and_free (deps, insn, &reg_last->uses, 0,
					    REG_DEP_ANTI, true);
	      add_dependence_list_and_free (deps, insn,
					    &reg_last->control_uses, 0,
					    REG_DEP_CONTROL, true);
	      add_dependence_list_and_free (deps, insn, &reg_last->sets, 0,
					    reg_pending_barrier == TRUE_BARRIER
					    ? REG_DEP_TRUE : REG_DEP_ANTI,
					    true);
	      add_dependence_list_and_free (deps, insn,
					    &reg_last->implicit_sets, 0,
					    REG_DEP_ANTI, true);
	      add_dependence_list_and_free (deps, insn, &reg_last->clobbers, 0,
					    reg_pending_barrier == TRUE_BARRIER
					    ? REG_DEP_TRUE : REG_DEP_ANTI,
					    true);

              if (!deps->readonly)
                {
                  reg_last->uses_length = 0;
                  reg_last->clobbers_length = 0;
                }
	    }
	}

      if (!deps->readonly)
        for (i = 0; i < (unsigned)deps->max_reg; i++)
          {
            struct deps_reg *reg_last = &deps->reg_last[i];
            reg_last->sets = alloc_INSN_LIST (insn, reg_last->sets);
            SET_REGNO_REG_SET (&deps->reg_last_in_use, i);
          }

      /* Don't flush pending lists on speculative checks for
	 selective scheduling.  */
      if (!sel_sched_p () || !sel_insn_is_speculation_check (insn))
	flush_pending_lists (deps, insn, true, true);

      reg_pending_barrier = NOT_A_BARRIER;
    }

  /* If a post-call group is still open, see if it should remain so.
     This insn must be a simple move of a hard reg to a pseudo or
     vice-versa.

     We must avoid moving these insns for correctness on targets
     with small register classes, and for special registers like
     PIC_OFFSET_TABLE_REGNUM.  For simplicity, extend this to all
     hard regs for all targets.  */

  if (deps->in_post_call_group_p)
    {
      rtx tmp, set = single_set (insn);
      int src_regno, dest_regno;

      if (set == NULL)
	{
	  if (DEBUG_INSN_P (insn))
	    /* We don't want to mark debug insns as part of the same
	       sched group.  We know they really aren't, but if we use
	       debug insns to tell that a call group is over, we'll
	       get different code if debug insns are not there and
	       instructions that follow seem like they should be part
	       of the call group.

	       Also, if we did, chain_to_prev_insn would move the
	       deps of the debug insn to the call insn, modifying
	       non-debug post-dependency counts of the debug insn
	       dependencies and otherwise messing with the scheduling
	       order.

	       Instead, let such debug insns be scheduled freely, but
	       keep the call group open in case there are insns that
	       should be part of it afterwards.  Since we grant debug
	       insns higher priority than even sched group insns, it
	       will all turn out all right.  */
	    goto debug_dont_end_call_group;
	  else
	    goto end_call_group;
	}

      tmp = SET_DEST (set);
      if (GET_CODE (tmp) == SUBREG)
	tmp = SUBREG_REG (tmp);
      if (REG_P (tmp))
	dest_regno = REGNO (tmp);
      else
	goto end_call_group;

      tmp = SET_SRC (set);
      if (GET_CODE (tmp) == SUBREG)
	tmp = SUBREG_REG (tmp);
      if ((GET_CODE (tmp) == PLUS
	   || GET_CODE (tmp) == MINUS)
	  && REG_P (XEXP (tmp, 0))
	  && REGNO (XEXP (tmp, 0)) == STACK_POINTER_REGNUM
	  && dest_regno == STACK_POINTER_REGNUM)
	src_regno = STACK_POINTER_REGNUM;
      else if (REG_P (tmp))
	src_regno = REGNO (tmp);
      else
	goto end_call_group;

      if (src_regno < FIRST_PSEUDO_REGISTER
	  || dest_regno < FIRST_PSEUDO_REGISTER)
	{
	  if (!deps->readonly
              && deps->in_post_call_group_p == post_call_initial)
	    deps->in_post_call_group_p = post_call;

          if (!sel_sched_p () || sched_emulate_haifa_p)
            {
              SCHED_GROUP_P (insn) = 1;
              CANT_MOVE (insn) = 1;
            }
	}
      else
	{
	end_call_group:
          if (!deps->readonly)
            deps->in_post_call_group_p = not_post_call;
	}
    }

 debug_dont_end_call_group:
  if ((current_sched_info->flags & DO_SPECULATION)
      && !sched_insn_is_legitimate_for_speculation_p (insn, 0))
    /* INSN has an internal dependency (e.g. r14 = [r14]) and thus cannot
       be speculated.  */
    {
      if (sel_sched_p ())
        sel_mark_hard_insn (insn);
      else
        {
          sd_iterator_def sd_it;
          dep_t dep;

          for (sd_it = sd_iterator_start (insn, SD_LIST_SPEC_BACK);
               sd_iterator_cond (&sd_it, &dep);)
            change_spec_dep_to_hard (sd_it);
        }
    }

  /* We do not yet have code to adjust REG_ARGS_SIZE, therefore we must
     honor their original ordering.  */
  if (find_reg_note (insn, REG_ARGS_SIZE, NULL))
    {
      if (deps->last_args_size)
	add_dependence (insn, deps->last_args_size, REG_DEP_OUTPUT);
      if (!deps->readonly)
	deps->last_args_size = insn;
    }

  /* We must not mix prologue and epilogue insns.  See PR78029.  */
  if (prologue_contains (insn))
    {
      add_dependence_list (insn, deps->last_epilogue, true, REG_DEP_ANTI, true);
      if (!deps->readonly)
	{
	  if (deps->last_logue_was_epilogue)
	    free_INSN_LIST_list (&deps->last_prologue);
	  deps->last_prologue = alloc_INSN_LIST (insn, deps->last_prologue);
	  deps->last_logue_was_epilogue = false;
	}
    }

  if (epilogue_contains (insn))
    {
      add_dependence_list (insn, deps->last_prologue, true, REG_DEP_ANTI, true);
      if (!deps->readonly)
	{
	  if (!deps->last_logue_was_epilogue)
	    free_INSN_LIST_list (&deps->last_epilogue);
	  deps->last_epilogue = alloc_INSN_LIST (insn, deps->last_epilogue);
	  deps->last_logue_was_epilogue = true;
	}
    }
}

/* Return TRUE if INSN might not always return normally (e.g. call exit,
   longjmp, loop forever, ...).  */
/* FIXME: Why can't this function just use flags_from_decl_or_type and
   test for ECF_NORETURN?  */
static bool
call_may_noreturn_p (rtx_insn *insn)
{
  rtx call;

  /* const or pure calls that aren't looping will always return.  */
  if (RTL_CONST_OR_PURE_CALL_P (insn)
      && !RTL_LOOPING_CONST_OR_PURE_CALL_P (insn))
    return false;

  call = get_call_rtx_from (insn);
  if (call && GET_CODE (XEXP (XEXP (call, 0), 0)) == SYMBOL_REF)
    {
      rtx symbol = XEXP (XEXP (call, 0), 0);
      if (SYMBOL_REF_DECL (symbol)
	  && TREE_CODE (SYMBOL_REF_DECL (symbol)) == FUNCTION_DECL)
	{
	  if (DECL_BUILT_IN_CLASS (SYMBOL_REF_DECL (symbol))
	      == BUILT_IN_NORMAL)
	    switch (DECL_FUNCTION_CODE (SYMBOL_REF_DECL (symbol)))
	      {
	      case BUILT_IN_BCMP:
	      case BUILT_IN_BCOPY:
	      case BUILT_IN_BZERO:
	      case BUILT_IN_INDEX:
	      case BUILT_IN_MEMCHR:
	      case BUILT_IN_MEMCMP:
	      case BUILT_IN_MEMCPY:
	      case BUILT_IN_MEMMOVE:
	      case BUILT_IN_MEMPCPY:
	      case BUILT_IN_MEMSET:
	      case BUILT_IN_RINDEX:
	      case BUILT_IN_STPCPY:
	      case BUILT_IN_STPNCPY:
	      case BUILT_IN_STRCAT:
	      case BUILT_IN_STRCHR:
	      case BUILT_IN_STRCMP:
	      case BUILT_IN_STRCPY:
	      case BUILT_IN_STRCSPN:
	      case BUILT_IN_STRLEN:
	      case BUILT_IN_STRNCAT:
	      case BUILT_IN_STRNCMP:
	      case BUILT_IN_STRNCPY:
	      case BUILT_IN_STRPBRK:
	      case BUILT_IN_STRRCHR:
	      case BUILT_IN_STRSPN:
	      case BUILT_IN_STRSTR:
		/* Assume certain string/memory builtins always return.  */
		return false;
	      default:
		break;
	      }
	}
    }

  /* For all other calls assume that they might not always return.  */
  return true;
}

/* Return true if INSN should be made dependent on the previous instruction
   group, and if all INSN's dependencies should be moved to the first
   instruction of that group.  */

static bool
chain_to_prev_insn_p (rtx_insn *insn)
{
  /* INSN forms a group with the previous instruction.  */
  if (SCHED_GROUP_P (insn))
    return true;

  /* If the previous instruction clobbers a register R and this one sets
     part of R, the clobber was added specifically to help us track the
     liveness of R.  There's no point scheduling the clobber and leaving
     INSN behind, especially if we move the clobber to another block.  */
  rtx_insn *prev = prev_nonnote_nondebug_insn (insn);
  if (prev
      && INSN_P (prev)
      && BLOCK_FOR_INSN (prev) == BLOCK_FOR_INSN (insn)
      && GET_CODE (PATTERN (prev)) == CLOBBER)
    {
      rtx x = XEXP (PATTERN (prev), 0);
      if (set_of (x, insn))
	return true;
    }

  return false;
}

/* Analyze INSN with DEPS as a context.  */
void
deps_analyze_insn (class deps_desc *deps, rtx_insn *insn)
{
  if (sched_deps_info->start_insn)
    sched_deps_info->start_insn (insn);

  /* Record the condition for this insn.  */
  if (NONDEBUG_INSN_P (insn))
    {
      rtx t;
      sched_get_condition_with_rev (insn, NULL);
      t = INSN_CACHED_COND (insn);
      INSN_COND_DEPS (insn) = NULL;
      if (reload_completed
	  && (current_sched_info->flags & DO_PREDICATION)
	  && COMPARISON_P (t)
	  && REG_P (XEXP (t, 0))
	  && CONSTANT_P (XEXP (t, 1)))
	{
	  unsigned int regno;
	  int nregs;
	  rtx_insn_list *cond_deps = NULL;
	  t = XEXP (t, 0);
	  regno = REGNO (t);
	  nregs = REG_NREGS (t);
	  while (nregs-- > 0)
	    {
	      struct deps_reg *reg_last = &deps->reg_last[regno + nregs];
	      cond_deps = concat_INSN_LIST (reg_last->sets, cond_deps);
	      cond_deps = concat_INSN_LIST (reg_last->clobbers, cond_deps);
	      cond_deps = concat_INSN_LIST (reg_last->implicit_sets, cond_deps);
	    }
	  INSN_COND_DEPS (insn) = cond_deps;
	}
    }

  if (JUMP_P (insn))
    {
      /* Make each JUMP_INSN (but not a speculative check)
         a scheduling barrier for memory references.  */
      if (!deps->readonly
          && !(sel_sched_p ()
               && sel_insn_is_speculation_check (insn)))
        {
          /* Keep the list a reasonable size.  */
	  if (deps->pending_flush_length++ >= param_max_pending_list_length)
	    flush_pending_lists (deps, insn, true, true);
          else
	    deps->pending_jump_insns
              = alloc_INSN_LIST (insn, deps->pending_jump_insns);
        }

      /* For each insn which shouldn't cross a jump, add a dependence.  */
      add_dependence_list_and_free (deps, insn,
				    &deps->sched_before_next_jump, 1,
				    REG_DEP_ANTI, true);

      sched_analyze_insn (deps, PATTERN (insn), insn);
    }
  else if (NONJUMP_INSN_P (insn) || DEBUG_INSN_P (insn))
    {
      sched_analyze_insn (deps, PATTERN (insn), insn);
    }
  else if (CALL_P (insn))
    {
      int i;

      CANT_MOVE (insn) = 1;

      if (!reload_completed)
	{
	  /* Scheduling across calls may increase register pressure by extending
	     live ranges of pseudos over the call.  Worse, in presence of setjmp
	     it may incorrectly move up an assignment over a longjmp.  */
	  reg_pending_barrier = MOVE_BARRIER;
	}
      else if (find_reg_note (insn, REG_SETJMP, NULL))
        {
          /* This is setjmp.  Assume that all registers, not just
             hard registers, may be clobbered by this call.  */
          reg_pending_barrier = MOVE_BARRIER;
        }
      else
        {
	  function_abi callee_abi = insn_callee_abi (insn);
          for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
            /* A call may read and modify global register variables.  */
            if (global_regs[i])
              {
                SET_REGNO_REG_SET (reg_pending_sets, i);
                SET_HARD_REG_BIT (implicit_reg_pending_uses, i);
              }
          /* Other call-clobbered hard regs may be clobbered.
             Since we only have a choice between 'might be clobbered'
             and 'definitely not clobbered', we must include all
             partly call-clobbered registers here.  */
	    else if (callee_abi.clobbers_at_least_part_of_reg_p (i))
              SET_REGNO_REG_SET (reg_pending_clobbers, i);
          /* We don't know what set of fixed registers might be used
             by the function, but it is certain that the stack pointer
             is among them, but be conservative.  */
            else if (fixed_regs[i])
	      SET_HARD_REG_BIT (implicit_reg_pending_uses, i);
          /* The frame pointer is normally not used by the function
             itself, but by the debugger.  */
          /* ??? MIPS o32 is an exception.  It uses the frame pointer
             in the macro expansion of jal but does not represent this
             fact in the call_insn rtl.  */
            else if (i == FRAME_POINTER_REGNUM
                     || (i == HARD_FRAME_POINTER_REGNUM
                         && (! reload_completed || frame_pointer_needed)))
	      SET_HARD_REG_BIT (implicit_reg_pending_uses, i);
        }

      /* For each insn which shouldn't cross a call, add a dependence
         between that insn and this call insn.  */
      add_dependence_list_and_free (deps, insn,
                                    &deps->sched_before_next_call, 1,
                                    REG_DEP_ANTI, true);

      sched_analyze_insn (deps, PATTERN (insn), insn);

      /* If CALL would be in a sched group, then this will violate
	 convention that sched group insns have dependencies only on the
	 previous instruction.

	 Of course one can say: "Hey!  What about head of the sched group?"
	 And I will answer: "Basic principles (one dep per insn) are always
	 the same."  */
      gcc_assert (!SCHED_GROUP_P (insn));

      /* In the absence of interprocedural alias analysis, we must flush
         all pending reads and writes, and start new dependencies starting
         from here.  But only flush writes for constant calls (which may
         be passed a pointer to something we haven't written yet).  */
      flush_pending_lists (deps, insn, true, ! RTL_CONST_OR_PURE_CALL_P (insn));

      if (!deps->readonly)
        {
          /* Remember the last function call for limiting lifetimes.  */
          free_INSN_LIST_list (&deps->last_function_call);
          deps->last_function_call = alloc_INSN_LIST (insn, NULL_RTX);

	  if (call_may_noreturn_p (insn))
	    {
	      /* Remember the last function call that might not always return
		 normally for limiting moves of trapping insns.  */
	      free_INSN_LIST_list (&deps->last_function_call_may_noreturn);
	      deps->last_function_call_may_noreturn
		= alloc_INSN_LIST (insn, NULL_RTX);
	    }

          /* Before reload, begin a post-call group, so as to keep the
             lifetimes of hard registers correct.  */
          if (! reload_completed)
            deps->in_post_call_group_p = post_call;
        }
    }

  if (sched_deps_info->use_cselib)
    cselib_process_insn (insn);

  if (sched_deps_info->finish_insn)
    sched_deps_info->finish_insn ();

  /* Fixup the dependencies in the sched group.  */
  if ((NONJUMP_INSN_P (insn) || JUMP_P (insn))
      && chain_to_prev_insn_p (insn)
      && !sel_sched_p ())
    chain_to_prev_insn (insn);
}

/* Initialize DEPS for the new block beginning with HEAD.  */
void
deps_start_bb (class deps_desc *deps, rtx_insn *head)
{
  gcc_assert (!deps->readonly);

  /* Before reload, if the previous block ended in a call, show that
     we are inside a post-call group, so as to keep the lifetimes of
     hard registers correct.  */
  if (! reload_completed && !LABEL_P (head))
    {
      rtx_insn *insn = prev_nonnote_nondebug_insn (head);

      if (insn && CALL_P (insn))
	deps->in_post_call_group_p = post_call_initial;
    }
}

/* Analyze every insn between HEAD and TAIL inclusive, creating backward
   dependencies for each insn.  */
void
sched_analyze (class deps_desc *deps, rtx_insn *head, rtx_insn *tail)
{
  rtx_insn *insn;

  if (sched_deps_info->use_cselib)
    cselib_init (CSELIB_RECORD_MEMORY);

  deps_start_bb (deps, head);

  for (insn = head;; insn = NEXT_INSN (insn))
    {
      if (INSN_P (insn))
	{
	  /* And initialize deps_lists.  */
	  sd_init_insn (insn);
	  /* Clean up SCHED_GROUP_P which may be set by last
	     scheduler pass.  */
	  if (SCHED_GROUP_P (insn))
	    SCHED_GROUP_P (insn) = 0;
	}

      deps_analyze_insn (deps, insn);

      if (insn == tail)
	{
	  if (sched_deps_info->use_cselib)
	    cselib_finish ();
	  return;
	}
    }
}

/* Helper for sched_free_deps ().
   Delete INSN's (RESOLVED_P) backward dependencies.  */
static void
delete_dep_nodes_in_back_deps (rtx_insn *insn, bool resolved_p)
{
  sd_iterator_def sd_it;
  dep_t dep;
  sd_list_types_def types;

  if (resolved_p)
    types = SD_LIST_RES_BACK;
  else
    types = SD_LIST_BACK;

  for (sd_it = sd_iterator_start (insn, types);
       sd_iterator_cond (&sd_it, &dep);)
    {
      dep_link_t link = *sd_it.linkp;
      dep_node_t node = DEP_LINK_NODE (link);
      deps_list_t back_list;
      deps_list_t forw_list;

      get_back_and_forw_lists (dep, resolved_p, &back_list, &forw_list);
      remove_from_deps_list (link, back_list);
      delete_dep_node (node);
    }
}

/* Delete (RESOLVED_P) dependencies between HEAD and TAIL together with
   deps_lists.  */
void
sched_free_deps (rtx_insn *head, rtx_insn *tail, bool resolved_p)
{
  rtx_insn *insn;
  rtx_insn *next_tail = NEXT_INSN (tail);

  /* We make two passes since some insns may be scheduled before their
     dependencies are resolved.  */
  for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
    if (INSN_P (insn) && INSN_LUID (insn) > 0)
      {
	/* Clear forward deps and leave the dep_nodes to the
	   corresponding back_deps list.  */
	if (resolved_p)
	  clear_deps_list (INSN_RESOLVED_FORW_DEPS (insn));
	else
	  clear_deps_list (INSN_FORW_DEPS (insn));
      }
  for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
    if (INSN_P (insn) && INSN_LUID (insn) > 0)
      {
	/* Clear resolved back deps together with its dep_nodes.  */
	delete_dep_nodes_in_back_deps (insn, resolved_p);

	sd_finish_insn (insn);
      }
}

/* Initialize variables for region data dependence analysis.
   When LAZY_REG_LAST is true, do not allocate reg_last array
   of class deps_desc immediately.  */

void
init_deps (class deps_desc *deps, bool lazy_reg_last)
{
  int max_reg = (reload_completed ? FIRST_PSEUDO_REGISTER : max_reg_num ());

  deps->max_reg = max_reg;
  if (lazy_reg_last)
    deps->reg_last = NULL;
  else
    deps->reg_last = XCNEWVEC (struct deps_reg, max_reg);
  INIT_REG_SET (&deps->reg_last_in_use);

  deps->pending_read_insns = 0;
  deps->pending_read_mems = 0;
  deps->pending_write_insns = 0;
  deps->pending_write_mems = 0;
  deps->pending_jump_insns = 0;
  deps->pending_read_list_length = 0;
  deps->pending_write_list_length = 0;
  deps->pending_flush_length = 0;
  deps->last_pending_memory_flush = 0;
  deps->last_function_call = 0;
  deps->last_function_call_may_noreturn = 0;
  deps->sched_before_next_call = 0;
  deps->sched_before_next_jump = 0;
  deps->in_post_call_group_p = not_post_call;
  deps->last_debug_insn = 0;
  deps->last_args_size = 0;
  deps->last_prologue = 0;
  deps->last_epilogue = 0;
  deps->last_logue_was_epilogue = false;
  deps->last_reg_pending_barrier = NOT_A_BARRIER;
  deps->readonly = 0;
}

/* Init only reg_last field of DEPS, which was not allocated before as
   we inited DEPS lazily.  */
void
init_deps_reg_last (class deps_desc *deps)
{
  gcc_assert (deps && deps->max_reg > 0);
  gcc_assert (deps->reg_last == NULL);

  deps->reg_last = XCNEWVEC (struct deps_reg, deps->max_reg);
}


/* Free insn lists found in DEPS.  */

void
free_deps (class deps_desc *deps)
{
  unsigned i;
  reg_set_iterator rsi;

  /* We set max_reg to 0 when this context was already freed.  */
  if (deps->max_reg == 0)
    {
      gcc_assert (deps->reg_last == NULL);
      return;
    }
  deps->max_reg = 0;

  free_INSN_LIST_list (&deps->pending_read_insns);
  free_EXPR_LIST_list (&deps->pending_read_mems);
  free_INSN_LIST_list (&deps->pending_write_insns);
  free_EXPR_LIST_list (&deps->pending_write_mems);
  free_INSN_LIST_list (&deps->last_pending_memory_flush);

  /* Without the EXECUTE_IF_SET, this loop is executed max_reg * nr_regions
     times.  For a testcase with 42000 regs and 8000 small basic blocks,
     this loop accounted for nearly 60% (84 sec) of the total -O2 runtime.  */
  EXECUTE_IF_SET_IN_REG_SET (&deps->reg_last_in_use, 0, i, rsi)
    {
      struct deps_reg *reg_last = &deps->reg_last[i];
      if (reg_last->uses)
	free_INSN_LIST_list (&reg_last->uses);
      if (reg_last->sets)
	free_INSN_LIST_list (&reg_last->sets);
      if (reg_last->implicit_sets)
	free_INSN_LIST_list (&reg_last->implicit_sets);
      if (reg_last->control_uses)
	free_INSN_LIST_list (&reg_last->control_uses);
      if (reg_last->clobbers)
	free_INSN_LIST_list (&reg_last->clobbers);
    }
  CLEAR_REG_SET (&deps->reg_last_in_use);

  /* As we initialize reg_last lazily, it is possible that we didn't allocate
     it at all.  */
  free (deps->reg_last);
  deps->reg_last = NULL;

  deps = NULL;
}

/* Remove INSN from dependence contexts DEPS.  */
void
remove_from_deps (class deps_desc *deps, rtx_insn *insn)
{
  int removed;
  unsigned i;
  reg_set_iterator rsi;

  removed = remove_from_both_dependence_lists (insn, &deps->pending_read_insns,
                                               &deps->pending_read_mems);
  if (!DEBUG_INSN_P (insn))
    deps->pending_read_list_length -= removed;
  removed = remove_from_both_dependence_lists (insn, &deps->pending_write_insns,
                                               &deps->pending_write_mems);
  deps->pending_write_list_length -= removed;

  removed = remove_from_dependence_list (insn, &deps->pending_jump_insns);
  deps->pending_flush_length -= removed;
  removed = remove_from_dependence_list (insn, &deps->last_pending_memory_flush);
  deps->pending_flush_length -= removed;

  unsigned to_clear = -1U;
  EXECUTE_IF_SET_IN_REG_SET (&deps->reg_last_in_use, 0, i, rsi)
    {
      if (to_clear != -1U)
	{
	  CLEAR_REGNO_REG_SET (&deps->reg_last_in_use, to_clear);
	  to_clear = -1U;
	}
      struct deps_reg *reg_last = &deps->reg_last[i];
      if (reg_last->uses)
	remove_from_dependence_list (insn, &reg_last->uses);
      if (reg_last->sets)
	remove_from_dependence_list (insn, &reg_last->sets);
      if (reg_last->implicit_sets)
	remove_from_dependence_list (insn, &reg_last->implicit_sets);
      if (reg_last->clobbers)
	remove_from_dependence_list (insn, &reg_last->clobbers);
      if (!reg_last->uses && !reg_last->sets && !reg_last->implicit_sets
	  && !reg_last->clobbers)
	to_clear = i;
    }
  if (to_clear != -1U)
    CLEAR_REGNO_REG_SET (&deps->reg_last_in_use, to_clear);

  if (CALL_P (insn))
    {
      remove_from_dependence_list (insn, &deps->last_function_call);
      remove_from_dependence_list (insn,
				   &deps->last_function_call_may_noreturn);
    }
  remove_from_dependence_list (insn, &deps->sched_before_next_call);
}

/* Init deps data vector.  */
static void
init_deps_data_vector (void)
{
  int reserve = (sched_max_luid + 1 - h_d_i_d.length ());
  if (reserve > 0 && ! h_d_i_d.space (reserve))
    h_d_i_d.safe_grow_cleared (3 * sched_max_luid / 2, true);
}

/* If it is profitable to use them, initialize or extend (depending on
   GLOBAL_P) dependency data.  */
void
sched_deps_init (bool global_p)
{
  /* Average number of insns in the basic block.
     '+ 1' is used to make it nonzero.  */
  int insns_in_block = sched_max_luid / n_basic_blocks_for_fn (cfun) + 1;

  init_deps_data_vector ();

  /* We use another caching mechanism for selective scheduling, so
     we don't use this one.  */
  if (!sel_sched_p () && global_p && insns_in_block > 100 * 5)
    {
      /* ?!? We could save some memory by computing a per-region luid mapping
         which could reduce both the number of vectors in the cache and the
         size of each vector.  Instead we just avoid the cache entirely unless
         the average number of instructions in a basic block is very high.  See
         the comment before the declaration of true_dependency_cache for
         what we consider "very high".  */
      cache_size = 0;
      extend_dependency_caches (sched_max_luid, true);
    }

  if (global_p)
    {
      dl_pool = new object_allocator<_deps_list> ("deps_list");
				/* Allocate lists for one block at a time.  */
      dn_pool = new object_allocator<_dep_node> ("dep_node");
				/* Allocate nodes for one block at a time.  */
    }
}


/* Create or extend (depending on CREATE_P) dependency caches to
   size N.  */
void
extend_dependency_caches (int n, bool create_p)
{
  if (create_p || true_dependency_cache)
    {
      int i, luid = cache_size + n;

      true_dependency_cache = XRESIZEVEC (bitmap_head, true_dependency_cache,
					  luid);
      output_dependency_cache = XRESIZEVEC (bitmap_head,
					    output_dependency_cache, luid);
      anti_dependency_cache = XRESIZEVEC (bitmap_head, anti_dependency_cache,
					  luid);
      control_dependency_cache = XRESIZEVEC (bitmap_head, control_dependency_cache,
					  luid);

      if (current_sched_info->flags & DO_SPECULATION)
        spec_dependency_cache = XRESIZEVEC (bitmap_head, spec_dependency_cache,
					    luid);

      for (i = cache_size; i < luid; i++)
	{
	  bitmap_initialize (&true_dependency_cache[i], 0);
	  bitmap_initialize (&output_dependency_cache[i], 0);
	  bitmap_initialize (&anti_dependency_cache[i], 0);
	  bitmap_initialize (&control_dependency_cache[i], 0);

          if (current_sched_info->flags & DO_SPECULATION)
            bitmap_initialize (&spec_dependency_cache[i], 0);
	}
      cache_size = luid;
    }
}

/* Finalize dependency information for the whole function.  */
void
sched_deps_finish (void)
{
  gcc_assert (deps_pools_are_empty_p ());
  delete dn_pool;
  delete dl_pool;
  dn_pool = NULL;
  dl_pool = NULL;

  h_d_i_d.release ();
  cache_size = 0;

  if (true_dependency_cache)
    {
      int i;

      for (i = 0; i < cache_size; i++)
	{
	  bitmap_clear (&true_dependency_cache[i]);
	  bitmap_clear (&output_dependency_cache[i]);
	  bitmap_clear (&anti_dependency_cache[i]);
	  bitmap_clear (&control_dependency_cache[i]);

          if (sched_deps_info->generate_spec_deps)
            bitmap_clear (&spec_dependency_cache[i]);
	}
      free (true_dependency_cache);
      true_dependency_cache = NULL;
      free (output_dependency_cache);
      output_dependency_cache = NULL;
      free (anti_dependency_cache);
      anti_dependency_cache = NULL;
      free (control_dependency_cache);
      control_dependency_cache = NULL;

      if (sched_deps_info->generate_spec_deps)
        {
          free (spec_dependency_cache);
          spec_dependency_cache = NULL;
        }

    }
}

/* Initialize some global variables needed by the dependency analysis
   code.  */

void
init_deps_global (void)
{
  CLEAR_HARD_REG_SET (implicit_reg_pending_clobbers);
  CLEAR_HARD_REG_SET (implicit_reg_pending_uses);
  reg_pending_sets = ALLOC_REG_SET (&reg_obstack);
  reg_pending_clobbers = ALLOC_REG_SET (&reg_obstack);
  reg_pending_uses = ALLOC_REG_SET (&reg_obstack);
  reg_pending_control_uses = ALLOC_REG_SET (&reg_obstack);
  reg_pending_barrier = NOT_A_BARRIER;

  if (!sel_sched_p () || sched_emulate_haifa_p)
    {
      sched_deps_info->start_insn = haifa_start_insn;
      sched_deps_info->finish_insn = haifa_finish_insn;

      sched_deps_info->note_reg_set = haifa_note_reg_set;
      sched_deps_info->note_reg_clobber = haifa_note_reg_clobber;
      sched_deps_info->note_reg_use = haifa_note_reg_use;

      sched_deps_info->note_mem_dep = haifa_note_mem_dep;
      sched_deps_info->note_dep = haifa_note_dep;
   }
}

/* Free everything used by the dependency analysis code.  */

void
finish_deps_global (void)
{
  FREE_REG_SET (reg_pending_sets);
  FREE_REG_SET (reg_pending_clobbers);
  FREE_REG_SET (reg_pending_uses);
  FREE_REG_SET (reg_pending_control_uses);
}

/* Estimate the weakness of dependence between MEM1 and MEM2.  */
dw_t
estimate_dep_weak (rtx mem1, rtx mem2)
{
  if (mem1 == mem2)
    /* MEMs are the same - don't speculate.  */
    return MIN_DEP_WEAK;

  rtx r1 = XEXP (mem1, 0);
  rtx r2 = XEXP (mem2, 0);

  if (sched_deps_info->use_cselib)
    {
      /* We cannot call rtx_equal_for_cselib_p because the VALUEs might be
	 dangling at this point, since we never preserve them.  Instead we
	 canonicalize manually to get stable VALUEs out of hashing.  */
      if (GET_CODE (r1) == VALUE && CSELIB_VAL_PTR (r1))
	r1 = canonical_cselib_val (CSELIB_VAL_PTR (r1))->val_rtx;
      if (GET_CODE (r2) == VALUE && CSELIB_VAL_PTR (r2))
	r2 = canonical_cselib_val (CSELIB_VAL_PTR (r2))->val_rtx;
    }

  if (r1 == r2
      || (REG_P (r1) && REG_P (r2) && REGNO (r1) == REGNO (r2)))
    /* Again, MEMs are the same.  */
    return MIN_DEP_WEAK;
  else if ((REG_P (r1) && !REG_P (r2)) || (!REG_P (r1) && REG_P (r2)))
    /* Different addressing modes - reason to be more speculative,
       than usual.  */
    return NO_DEP_WEAK - (NO_DEP_WEAK - UNCERTAIN_DEP_WEAK) / 2;
  else
    /* We can't say anything about the dependence.  */
    return UNCERTAIN_DEP_WEAK;
}

/* Add or update backward dependence between INSN and ELEM with type DEP_TYPE.
   This function can handle same INSN and ELEM (INSN == ELEM).
   It is a convenience wrapper.  */
static void
add_dependence_1 (rtx_insn *insn, rtx_insn *elem, enum reg_note dep_type)
{
  ds_t ds;
  bool internal;

  if (dep_type == REG_DEP_TRUE)
    ds = DEP_TRUE;
  else if (dep_type == REG_DEP_OUTPUT)
    ds = DEP_OUTPUT;
  else if (dep_type == REG_DEP_CONTROL)
    ds = DEP_CONTROL;
  else
    {
      gcc_assert (dep_type == REG_DEP_ANTI);
      ds = DEP_ANTI;
    }

  /* When add_dependence is called from inside sched-deps.cc, we expect
     cur_insn to be non-null.  */
  internal = cur_insn != NULL;
  if (internal)
    gcc_assert (insn == cur_insn);
  else
    cur_insn = insn;

  note_dep (elem, ds);
  if (!internal)
    cur_insn = NULL;
}

/* Return weakness of speculative type TYPE in the dep_status DS,
   without checking to prevent ICEs on malformed input.  */
static dw_t
get_dep_weak_1 (ds_t ds, ds_t type)
{
  ds = ds & type;

  switch (type)
    {
    case BEGIN_DATA: ds >>= BEGIN_DATA_BITS_OFFSET; break;
    case BE_IN_DATA: ds >>= BE_IN_DATA_BITS_OFFSET; break;
    case BEGIN_CONTROL: ds >>= BEGIN_CONTROL_BITS_OFFSET; break;
    case BE_IN_CONTROL: ds >>= BE_IN_CONTROL_BITS_OFFSET; break;
    default: gcc_unreachable ();
    }

  return (dw_t) ds;
}

/* Return weakness of speculative type TYPE in the dep_status DS.  */
dw_t
get_dep_weak (ds_t ds, ds_t type)
{
  dw_t dw = get_dep_weak_1 (ds, type);

  gcc_assert (MIN_DEP_WEAK <= dw && dw <= MAX_DEP_WEAK);
  return dw;
}

/* Return the dep_status, which has the same parameters as DS, except for
   speculative type TYPE, that will have weakness DW.  */
ds_t
set_dep_weak (ds_t ds, ds_t type, dw_t dw)
{
  gcc_assert (MIN_DEP_WEAK <= dw && dw <= MAX_DEP_WEAK);

  ds &= ~type;
  switch (type)
    {
    case BEGIN_DATA: ds |= ((ds_t) dw) << BEGIN_DATA_BITS_OFFSET; break;
    case BE_IN_DATA: ds |= ((ds_t) dw) << BE_IN_DATA_BITS_OFFSET; break;
    case BEGIN_CONTROL: ds |= ((ds_t) dw) << BEGIN_CONTROL_BITS_OFFSET; break;
    case BE_IN_CONTROL: ds |= ((ds_t) dw) << BE_IN_CONTROL_BITS_OFFSET; break;
    default: gcc_unreachable ();
    }
  return ds;
}

/* Return the join of two dep_statuses DS1 and DS2.
   If MAX_P is true then choose the greater probability,
   otherwise multiply probabilities.
   This function assumes that both DS1 and DS2 contain speculative bits.  */
static ds_t
ds_merge_1 (ds_t ds1, ds_t ds2, bool max_p)
{
  ds_t ds, t;

  gcc_assert ((ds1 & SPECULATIVE) && (ds2 & SPECULATIVE));

  ds = (ds1 & DEP_TYPES) | (ds2 & DEP_TYPES);

  t = FIRST_SPEC_TYPE;
  do
    {
      if ((ds1 & t) && !(ds2 & t))
	ds |= ds1 & t;
      else if (!(ds1 & t) && (ds2 & t))
	ds |= ds2 & t;
      else if ((ds1 & t) && (ds2 & t))
	{
	  dw_t dw1 = get_dep_weak (ds1, t);
	  dw_t dw2 = get_dep_weak (ds2, t);
	  ds_t dw;

	  if (!max_p)
	    {
	      dw = ((ds_t) dw1) * ((ds_t) dw2);
	      dw /= MAX_DEP_WEAK;
	      if (dw < MIN_DEP_WEAK)
		dw = MIN_DEP_WEAK;
	    }
	  else
	    {
	      if (dw1 >= dw2)
		dw = dw1;
	      else
		dw = dw2;
	    }

	  ds = set_dep_weak (ds, t, (dw_t) dw);
	}

      if (t == LAST_SPEC_TYPE)
	break;
      t <<= SPEC_TYPE_SHIFT;
    }
  while (1);

  return ds;
}

/* Return the join of two dep_statuses DS1 and DS2.
   This function assumes that both DS1 and DS2 contain speculative bits.  */
ds_t
ds_merge (ds_t ds1, ds_t ds2)
{
  return ds_merge_1 (ds1, ds2, false);
}

/* Return the join of two dep_statuses DS1 and DS2.  */
ds_t
ds_full_merge (ds_t ds, ds_t ds2, rtx mem1, rtx mem2)
{
  ds_t new_status = ds | ds2;

  if (new_status & SPECULATIVE)
    {
      if ((ds && !(ds & SPECULATIVE))
	  || (ds2 && !(ds2 & SPECULATIVE)))
	/* Then this dep can't be speculative.  */
	new_status &= ~SPECULATIVE;
      else
	{
	  /* Both are speculative.  Merging probabilities.  */
	  if (mem1)
	    {
	      dw_t dw;

	      dw = estimate_dep_weak (mem1, mem2);
	      ds = set_dep_weak (ds, BEGIN_DATA, dw);
	    }

	  if (!ds)
	    new_status = ds2;
	  else if (!ds2)
	    new_status = ds;
	  else
	    new_status = ds_merge (ds2, ds);
	}
    }

  return new_status;
}

/* Return the join of DS1 and DS2.  Use maximum instead of multiplying
   probabilities.  */
ds_t
ds_max_merge (ds_t ds1, ds_t ds2)
{
  if (ds1 == 0 && ds2 == 0)
    return 0;

  if (ds1 == 0 && ds2 != 0)
    return ds2;

  if (ds1 != 0 && ds2 == 0)
    return ds1;

  return ds_merge_1 (ds1, ds2, true);
}

/* Return the probability of speculation success for the speculation
   status DS.  */
dw_t
ds_weak (ds_t ds)
{
  ds_t res = 1, dt;
  int n = 0;

  dt = FIRST_SPEC_TYPE;
  do
    {
      if (ds & dt)
	{
	  res *= (ds_t) get_dep_weak (ds, dt);
	  n++;
	}

      if (dt == LAST_SPEC_TYPE)
	break;
      dt <<= SPEC_TYPE_SHIFT;
    }
  while (1);

  gcc_assert (n);
  while (--n)
    res /= MAX_DEP_WEAK;

  if (res < MIN_DEP_WEAK)
    res = MIN_DEP_WEAK;

  gcc_assert (res <= MAX_DEP_WEAK);

  return (dw_t) res;
}

/* Return a dep status that contains all speculation types of DS.  */
ds_t
ds_get_speculation_types (ds_t ds)
{
  if (ds & BEGIN_DATA)
    ds |= BEGIN_DATA;
  if (ds & BE_IN_DATA)
    ds |= BE_IN_DATA;
  if (ds & BEGIN_CONTROL)
    ds |= BEGIN_CONTROL;
  if (ds & BE_IN_CONTROL)
    ds |= BE_IN_CONTROL;

  return ds & SPECULATIVE;
}

/* Return a dep status that contains maximal weakness for each speculation
   type present in DS.  */
ds_t
ds_get_max_dep_weak (ds_t ds)
{
  if (ds & BEGIN_DATA)
    ds = set_dep_weak (ds, BEGIN_DATA, MAX_DEP_WEAK);
  if (ds & BE_IN_DATA)
    ds = set_dep_weak (ds, BE_IN_DATA, MAX_DEP_WEAK);
  if (ds & BEGIN_CONTROL)
    ds = set_dep_weak (ds, BEGIN_CONTROL, MAX_DEP_WEAK);
  if (ds & BE_IN_CONTROL)
    ds = set_dep_weak (ds, BE_IN_CONTROL, MAX_DEP_WEAK);

  return ds;
}

/* Dump information about the dependence status S.  */
static void
dump_ds (FILE *f, ds_t s)
{
  fprintf (f, "{");

  if (s & BEGIN_DATA)
    fprintf (f, "BEGIN_DATA: %d; ", get_dep_weak_1 (s, BEGIN_DATA));
  if (s & BE_IN_DATA)
    fprintf (f, "BE_IN_DATA: %d; ", get_dep_weak_1 (s, BE_IN_DATA));
  if (s & BEGIN_CONTROL)
    fprintf (f, "BEGIN_CONTROL: %d; ", get_dep_weak_1 (s, BEGIN_CONTROL));
  if (s & BE_IN_CONTROL)
    fprintf (f, "BE_IN_CONTROL: %d; ", get_dep_weak_1 (s, BE_IN_CONTROL));

  if (s & HARD_DEP)
    fprintf (f, "HARD_DEP; ");

  if (s & DEP_TRUE)
    fprintf (f, "DEP_TRUE; ");
  if (s & DEP_OUTPUT)
    fprintf (f, "DEP_OUTPUT; ");
  if (s & DEP_ANTI)
    fprintf (f, "DEP_ANTI; ");
  if (s & DEP_CONTROL)
    fprintf (f, "DEP_CONTROL; ");

  fprintf (f, "}");
}

DEBUG_FUNCTION void
debug_ds (ds_t s)
{
  dump_ds (stderr, s);
  fprintf (stderr, "\n");
}

/* Verify that dependence type and status are consistent.
   If RELAXED_P is true, then skip dep_weakness checks.  */
static void
check_dep (dep_t dep, bool relaxed_p)
{
  enum reg_note dt = DEP_TYPE (dep);
  ds_t ds = DEP_STATUS (dep);

  gcc_assert (DEP_PRO (dep) != DEP_CON (dep));

  if (!(current_sched_info->flags & USE_DEPS_LIST))
    {
      gcc_assert (ds == 0);
      return;
    }

  /* Check that dependence type contains the same bits as the status.  */
  if (dt == REG_DEP_TRUE)
    gcc_assert (ds & DEP_TRUE);
  else if (dt == REG_DEP_OUTPUT)
    gcc_assert ((ds & DEP_OUTPUT)
		&& !(ds & DEP_TRUE));
  else if (dt == REG_DEP_ANTI)
    gcc_assert ((ds & DEP_ANTI)
		&& !(ds & (DEP_OUTPUT | DEP_TRUE)));
  else
    gcc_assert (dt == REG_DEP_CONTROL
		&& (ds & DEP_CONTROL)
		&& !(ds & (DEP_OUTPUT | DEP_ANTI | DEP_TRUE)));

  /* HARD_DEP cannot appear in dep_status of a link.  */
  gcc_assert (!(ds & HARD_DEP));

  /* Check that dependence status is set correctly when speculation is not
     supported.  */
  if (!sched_deps_info->generate_spec_deps)
    gcc_assert (!(ds & SPECULATIVE));
  else if (ds & SPECULATIVE)
    {
      if (!relaxed_p)
	{
	  ds_t type = FIRST_SPEC_TYPE;

	  /* Check that dependence weakness is in proper range.  */
	  do
	    {
	      if (ds & type)
		get_dep_weak (ds, type);

	      if (type == LAST_SPEC_TYPE)
		break;
	      type <<= SPEC_TYPE_SHIFT;
	    }
	  while (1);
	}

      if (ds & BEGIN_SPEC)
	{
	  /* Only true dependence can be data speculative.  */
	  if (ds & BEGIN_DATA)
	    gcc_assert (ds & DEP_TRUE);

	  /* Control dependencies in the insn scheduler are represented by
	     anti-dependencies, therefore only anti dependence can be
	     control speculative.  */
	  if (ds & BEGIN_CONTROL)
	    gcc_assert (ds & DEP_ANTI);
	}
      else
	{
	  /* Subsequent speculations should resolve true dependencies.  */
	  gcc_assert ((ds & DEP_TYPES) == DEP_TRUE);
	}

      /* Check that true and anti dependencies can't have other speculative
	 statuses.  */
      if (ds & DEP_TRUE)
	gcc_assert (ds & (BEGIN_DATA | BE_IN_SPEC));
      /* An output dependence can't be speculative at all.  */
      gcc_assert (!(ds & DEP_OUTPUT));
      if (ds & DEP_ANTI)
	gcc_assert (ds & BEGIN_CONTROL);
    }
}

/* The following code discovers opportunities to switch a memory reference
   and an increment by modifying the address.  We ensure that this is done
   only for dependencies that are only used to show a single register
   dependence (using DEP_NONREG and DEP_MULTIPLE), and so that every memory
   instruction involved is subject to only one dep that can cause a pattern
   change.

   When we discover a suitable dependency, we fill in the dep_replacement
   structure to show how to modify the memory reference.  */

/* Holds information about a pair of memory reference and register increment
   insns which depend on each other, but could possibly be interchanged.  */
struct mem_inc_info
{
  rtx_insn *inc_insn;
  rtx_insn *mem_insn;

  rtx *mem_loc;
  /* A register occurring in the memory address for which we wish to break
     the dependence.  This must be identical to the destination register of
     the increment.  */
  rtx mem_reg0;
  /* Any kind of index that is added to that register.  */
  rtx mem_index;
  /* The constant offset used in the memory address.  */
  HOST_WIDE_INT mem_constant;
  /* The constant added in the increment insn.  Negated if the increment is
     after the memory address.  */
  HOST_WIDE_INT inc_constant;
  /* The source register used in the increment.  May be different from mem_reg0
     if the increment occurs before the memory address.  */
  rtx inc_input;
};

/* Verify that the memory location described in MII can be replaced with
   one using NEW_ADDR.  Return the new memory reference or NULL_RTX.  The
   insn remains unchanged by this function.  */

static rtx
attempt_change (struct mem_inc_info *mii, rtx new_addr)
{
  rtx mem = *mii->mem_loc;
  rtx new_mem;

  if (!targetm.new_address_profitable_p (mem, mii->mem_insn, new_addr))
    return NULL_RTX;

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

  /* Put back the old one.  */
  validate_change (mii->mem_insn, mii->mem_loc, mem, 0);

  return new_mem;
}

/* Return true if INSN is of a form "a = b op c" where a and b are
   regs.  op is + if c is a reg and +|- if c is a const.  Fill in
   informantion in MII about what is found.
   BEFORE_MEM indicates whether the increment is found before or after
   a corresponding memory reference.  */

static bool
parse_add_or_inc (struct mem_inc_info *mii, rtx_insn *insn, bool before_mem)
{
  rtx pat = single_set (insn);
  rtx src, cst;
  bool regs_equal;

  if (RTX_FRAME_RELATED_P (insn) || !pat)
    return false;

  /* Do not allow breaking data dependencies for insns that are marked
     with REG_STACK_CHECK.  */
  if (find_reg_note (insn, REG_STACK_CHECK, NULL))
    return false;

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

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

  mii->inc_insn = insn;
  src = SET_SRC (pat);
  mii->inc_input = XEXP (src, 0);

  if (!REG_P (XEXP (src, 0)))
    return false;

  if (!rtx_equal_p (SET_DEST (pat), mii->mem_reg0))
    return false;

  cst = XEXP (src, 1);
  if (!CONST_INT_P (cst))
    return false;
  mii->inc_constant = INTVAL (cst);

  regs_equal = rtx_equal_p (mii->inc_input, mii->mem_reg0);

  if (!before_mem)
    {
      mii->inc_constant = -mii->inc_constant;
      if (!regs_equal)
	return false;
    }

  if (regs_equal && REGNO (SET_DEST (pat)) == STACK_POINTER_REGNUM)
    {
      /* Note that the sign has already been reversed for !before_mem.  */
      if (STACK_GROWS_DOWNWARD)
	return mii->inc_constant > 0;
      else
	return mii->inc_constant < 0;
    }
  return true;
}

/* Once a suitable mem reference has been found and the corresponding data
   in MII has been filled in, this function is called to find a suitable
   add or inc insn involving the register we found in the memory
   reference.
   If successful, this function will create additional dependencies between
   - mii->inc_insn's producers and mii->mem_insn as a consumer (if backwards)
   - mii->inc_insn's consumers and mii->mem_insn as a producer (if !backwards).
*/

static bool
find_inc (struct mem_inc_info *mii, bool backwards)
{
  sd_iterator_def sd_it;
  dep_t dep;
  sd_list_types_def mem_deps = backwards ? SD_LIST_HARD_BACK : SD_LIST_FORW;
  int n_mem_deps = dep_list_size (mii->mem_insn, mem_deps);

  sd_it = sd_iterator_start (mii->mem_insn, mem_deps);
  while (sd_iterator_cond (&sd_it, &dep))
    {
      dep_node_t node = DEP_LINK_NODE (*sd_it.linkp);
      rtx_insn *pro = DEP_PRO (dep);
      rtx_insn *con = DEP_CON (dep);
      rtx_insn *inc_cand;
      int n_inc_deps;

      if (DEP_NONREG (dep) || DEP_MULTIPLE (dep))
	goto next;

      if (backwards)
	{
	  inc_cand = pro;
	  n_inc_deps = dep_list_size (inc_cand, SD_LIST_BACK);
	}
      else
	{
	  inc_cand = con;
	  n_inc_deps = dep_list_size (inc_cand, SD_LIST_FORW);
	}

      /* In the FOR_EACH_DEP loop below we will create additional n_inc_deps
	 for mem_insn.  This by itself is not a problem, since each mem_insn
	 will have only a few inc_insns associated with it.  However, if
	 we consider that a single inc_insn may have a lot of mem_insns, AND,
	 on top of that, a few other inc_insns associated with it --
	 those _other inc_insns_ will get (n_mem_deps * number of MEM insns)
	 dependencies created for them.  This may cause an exponential
	 growth of memory usage and scheduling time.
	 See PR96388 for details.
	 We [heuristically] use n_inc_deps as a proxy for the number of MEM
	 insns, and drop opportunities for breaking modifiable_mem dependencies
	 when dependency lists grow beyond reasonable size.  */
      if (n_mem_deps * n_inc_deps
	  >= param_max_pending_list_length * param_max_pending_list_length)
	goto next;

      if (parse_add_or_inc (mii, inc_cand, backwards))
	{
	  struct dep_replacement *desc;
	  df_ref def;
	  rtx newaddr, newmem;

	  if (sched_verbose >= 5)
	    fprintf (sched_dump, "candidate mem/inc pair: %d %d\n",
		     INSN_UID (mii->mem_insn), INSN_UID (inc_cand));

	  /* Need to assure that none of the operands of the inc
	     instruction are assigned to by the mem insn.  */
	  FOR_EACH_INSN_DEF (def, mii->mem_insn)
	    if (reg_overlap_mentioned_p (DF_REF_REG (def), mii->inc_input)
		|| reg_overlap_mentioned_p (DF_REF_REG (def), mii->mem_reg0))
	      {
		if (sched_verbose >= 5)
		  fprintf (sched_dump,
			   "inc conflicts with store failure.\n");
		goto next;
	      }

	  newaddr = mii->inc_input;
	  if (mii->mem_index != NULL_RTX)
	    newaddr = gen_rtx_PLUS (GET_MODE (newaddr), newaddr,
				    mii->mem_index);
	  newaddr = plus_constant (GET_MODE (newaddr), newaddr,
				   mii->mem_constant + mii->inc_constant);
	  newmem = attempt_change (mii, newaddr);
	  if (newmem == NULL_RTX)
	    goto next;
	  if (sched_verbose >= 5)
	    fprintf (sched_dump, "successful address replacement\n");
	  desc = XCNEW (struct dep_replacement);
	  DEP_REPLACE (dep) = desc;
	  desc->loc = mii->mem_loc;
	  desc->newval = newmem;
	  desc->orig = *desc->loc;
	  desc->insn = mii->mem_insn;
	  move_dep_link (DEP_NODE_BACK (node), INSN_HARD_BACK_DEPS (con),
			 INSN_SPEC_BACK_DEPS (con));

	  /* Make sure that n_inc_deps above is consistent with dependencies
	     we create.  */
	  gcc_assert (mii->inc_insn == inc_cand);

	  if (backwards)
	    {
	      FOR_EACH_DEP (mii->inc_insn, SD_LIST_BACK, sd_it, dep)
		add_dependence_1 (mii->mem_insn, DEP_PRO (dep),
				  REG_DEP_TRUE);
	    }
	  else
	    {
	      FOR_EACH_DEP (mii->inc_insn, SD_LIST_FORW, sd_it, dep)
		add_dependence_1 (DEP_CON (dep), mii->mem_insn,
				  REG_DEP_ANTI);
	    }
	  return true;
	}
    next:
      sd_iterator_next (&sd_it);
    }
  return false;
}

/* A recursive function that walks ADDRESS_OF_X to find memory references
   which could be modified during scheduling.  We call find_inc for each
   one we find that has a recognizable form.  MII holds information about
   the pair of memory/increment instructions.
   We ensure that every instruction with a memory reference (which will be
   the location of the replacement) is assigned at most one breakable
   dependency.  */

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

  if (code == MEM)
    {
      rtx reg0 = XEXP (x, 0);

      mii->mem_loc = address_of_x;
      mii->mem_index = NULL_RTX;
      mii->mem_constant = 0;
      if (GET_CODE (reg0) == PLUS && CONST_INT_P (XEXP (reg0, 1)))
	{
	  mii->mem_constant = INTVAL (XEXP (reg0, 1));
	  reg0 = XEXP (reg0, 0);
	}
      if (GET_CODE (reg0) == PLUS)
	{
	  mii->mem_index = XEXP (reg0, 1);
	  reg0 = XEXP (reg0, 0);
	}
      if (REG_P (reg0))
	{
	  df_ref use;
	  int occurrences = 0;

	  /* Make sure this reg appears only once in this insn.  Can't use
	     count_occurrences since that only works for pseudos.  */
	  FOR_EACH_INSN_USE (use, mii->mem_insn)
	    if (reg_overlap_mentioned_p (reg0, DF_REF_REG (use)))
	      if (++occurrences > 1)
		{
		  if (sched_verbose >= 5)
		    fprintf (sched_dump, "mem count failure\n");
		  return false;
		}

	  mii->mem_reg0 = reg0;
	  return find_inc (mii, true) || find_inc (mii, false);
	}
      return false;
    }

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

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


/* Examine the instructions between HEAD and TAIL and try to find
   dependencies that can be broken by modifying one of the patterns.  */

void
find_modifiable_mems (rtx_insn *head, rtx_insn *tail)
{
  rtx_insn *insn, *next_tail = NEXT_INSN (tail);
  int success_in_block = 0;

  for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
    {
      struct mem_inc_info mii;

      if (!NONDEBUG_INSN_P (insn) || RTX_FRAME_RELATED_P (insn))
	continue;

      mii.mem_insn = insn;
      if (find_mem (&mii, &PATTERN (insn)))
	success_in_block++;
    }
  if (success_in_block && sched_verbose >= 5)
    fprintf (sched_dump, "%d candidates for address modification found.\n",
	     success_in_block);
}

#endif /* INSN_SCHEDULING */
