/* Instruction scheduling pass.
   Copyright (C) 1992-2021 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/>.  */

/* Instruction scheduling pass.  This file, along with sched-deps.c,
   contains the generic parts.  The actual entry point for
   the normal instruction scheduling pass is found in sched-rgn.c.

   We compute insn priorities based on data dependencies.  Flow
   analysis only creates a fraction of the data-dependencies we must
   observe: namely, only those dependencies which the combiner can be
   expected to use.  For this pass, we must therefore create the
   remaining dependencies we need to observe: register dependencies,
   memory dependencies, dependencies to keep function calls in order,
   and the dependence between a conditional branch and the setting of
   condition codes are all dealt with here.

   The scheduler first traverses the data flow graph, starting with
   the last instruction, and proceeding to the first, assigning values
   to insn_priority as it goes.  This sorts the instructions
   topologically by data dependence.

   Once priorities have been established, we order the insns using
   list scheduling.  This works as follows: starting with a list of
   all the ready insns, and sorted according to priority number, we
   schedule the insn from the end of the list by placing its
   predecessors in the list according to their priority order.  We
   consider this insn scheduled by setting the pointer to the "end" of
   the list to point to the previous insn.  When an insn has no
   predecessors, we either queue it until sufficient time has elapsed
   or add it to the ready list.  As the instructions are scheduled or
   when stalls are introduced, the queue advances and dumps insns into
   the ready list.  When all insns down to the lowest priority have
   been scheduled, the critical path of the basic block has been made
   as short as possible.  The remaining insns are then scheduled in
   remaining slots.

   The following list shows the order in which we want to break ties
   among insns in the ready list:

   1.  choose insn with the longest path to end of bb, ties
   broken by
   2.  choose insn with least contribution to register pressure,
   ties broken by
   3.  prefer in-block upon interblock motion, ties broken by
   4.  prefer useful upon speculative motion, ties broken by
   5.  choose insn with largest control flow probability, ties
   broken by
   6.  choose insn with the least dependences upon the previously
   scheduled insn, or finally
   7   choose the insn which has the most insns dependent on it.
   8.  choose insn with lowest UID.

   Memory references complicate matters.  Only if we can be certain
   that memory references are not part of the data dependency graph
   (via true, anti, or output dependence), can we move operations past
   memory references.  To first approximation, reads can be done
   independently, while writes introduce dependencies.  Better
   approximations will yield fewer dependencies.

   Before reload, an extended analysis of interblock data dependences
   is required for interblock scheduling.  This is performed in
   compute_block_dependences ().

   Dependencies set up by memory references are treated in exactly the
   same way as other dependencies, by using insn backward dependences
   INSN_BACK_DEPS.  INSN_BACK_DEPS are translated into forward dependences
   INSN_FORW_DEPS for the purpose of forward list scheduling.

   Having optimized the critical path, we may have also unduly
   extended the lifetimes of some registers.  If an operation requires
   that constants be loaded into registers, it is certainly desirable
   to load those constants as early as necessary, but no earlier.
   I.e., it will not do to load up a bunch of registers at the
   beginning of a basic block only to use them at the end, if they
   could be loaded later, since this may result in excessive register
   utilization.

   Note that since branches are never in basic blocks, but only end
   basic blocks, this pass will not move branches.  But that is ok,
   since we can use GNU's delayed branch scheduling pass to take care
   of this case.

   Also note that no further optimizations based on algebraic
   identities are performed, so this pass would be a good one to
   perform instruction splitting, such as breaking up a multiply
   instruction into shifts and adds where that is profitable.

   Given the memory aliasing analysis that this pass should perform,
   it should be possible to remove redundant stores to memory, and to
   load values from registers instead of hitting memory.

   Before reload, speculative insns are moved only if a 'proof' exists
   that no exception will be caused by this, and if no live registers
   exist that inhibit the motion (live registers constraints are not
   represented by data dependence edges).

   This pass must update information that subsequent passes expect to
   be correct.  Namely: reg_n_refs, reg_n_sets, reg_n_deaths,
   reg_n_calls_crossed, and reg_live_length.  Also, BB_HEAD, BB_END.

   The information in the line number notes is carefully retained by
   this pass.  Notes that refer to the starting and ending of
   exception regions are also carefully retained by this pass.  All
   other NOTE insns are grouped in their same relative order at the
   beginning of basic blocks and regions that have been scheduled.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "cfghooks.h"
#include "df.h"
#include "memmodel.h"
#include "tm_p.h"
#include "insn-config.h"
#include "regs.h"
#include "ira.h"
#include "recog.h"
#include "insn-attr.h"
#include "cfgrtl.h"
#include "cfgbuild.h"
#include "sched-int.h"
#include "common/common-target.h"
#include "dbgcnt.h"
#include "cfgloop.h"
#include "dumpfile.h"
#include "print-rtl.h"
#include "function-abi.h"

#ifdef INSN_SCHEDULING

/* True if we do register pressure relief through live-range
   shrinkage.  */
static bool live_range_shrinkage_p;

/* Switch on live range shrinkage.  */
void
initialize_live_range_shrinkage (void)
{
  live_range_shrinkage_p = true;
}

/* Switch off live range shrinkage.  */
void
finish_live_range_shrinkage (void)
{
  live_range_shrinkage_p = false;
}

/* issue_rate is the number of insns that can be scheduled in the same
   machine cycle.  It can be defined in the config/mach/mach.h file,
   otherwise we set it to 1.  */

int issue_rate;

/* This can be set to true by a backend if the scheduler should not
   enable a DCE pass.  */
bool sched_no_dce;

/* The current initiation interval used when modulo scheduling.  */
static int modulo_ii;

/* The maximum number of stages we are prepared to handle.  */
static int modulo_max_stages;

/* The number of insns that exist in each iteration of the loop.  We use this
   to detect when we've scheduled all insns from the first iteration.  */
static int modulo_n_insns;

/* The current count of insns in the first iteration of the loop that have
   already been scheduled.  */
static int modulo_insns_scheduled;

/* The maximum uid of insns from the first iteration of the loop.  */
static int modulo_iter0_max_uid;

/* The number of times we should attempt to backtrack when modulo scheduling.
   Decreased each time we have to backtrack.  */
static int modulo_backtracks_left;

/* The stage in which the last insn from the original loop was
   scheduled.  */
static int modulo_last_stage;

/* sched-verbose controls the amount of debugging output the
   scheduler prints.  It is controlled by -fsched-verbose=N:
   N=0: no debugging output.
   N=1: default value.
   N=2: bb's probabilities, detailed ready list info, unit/insn info.
   N=3: rtl at abort point, control-flow, regions info.
   N=5: dependences info.  */
int sched_verbose = 0;

/* Debugging file.  All printouts are sent to dump. */
FILE *sched_dump = 0;

/* This is a placeholder for the scheduler parameters common
   to all schedulers.  */
struct common_sched_info_def *common_sched_info;

#define INSN_TICK(INSN)	(HID (INSN)->tick)
#define INSN_EXACT_TICK(INSN) (HID (INSN)->exact_tick)
#define INSN_TICK_ESTIMATE(INSN) (HID (INSN)->tick_estimate)
#define INTER_TICK(INSN) (HID (INSN)->inter_tick)
#define FEEDS_BACKTRACK_INSN(INSN) (HID (INSN)->feeds_backtrack_insn)
#define SHADOW_P(INSN) (HID (INSN)->shadow_p)
#define MUST_RECOMPUTE_SPEC_P(INSN) (HID (INSN)->must_recompute_spec)
/* Cached cost of the instruction.  Use insn_sched_cost to get cost of the
   insn.  -1 here means that the field is not initialized.  */
#define INSN_COST(INSN)	(HID (INSN)->cost)

/* If INSN_TICK of an instruction is equal to INVALID_TICK,
   then it should be recalculated from scratch.  */
#define INVALID_TICK (-(max_insn_queue_index + 1))
/* The minimal value of the INSN_TICK of an instruction.  */
#define MIN_TICK (-max_insn_queue_index)

/* Original order of insns in the ready list.
   Used to keep order of normal insns while separating DEBUG_INSNs.  */
#define INSN_RFS_DEBUG_ORIG_ORDER(INSN) (HID (INSN)->rfs_debug_orig_order)

/* The deciding reason for INSN's place in the ready list.  */
#define INSN_LAST_RFS_WIN(INSN) (HID (INSN)->last_rfs_win)

/* List of important notes we must keep around.  This is a pointer to the
   last element in the list.  */
rtx_insn *note_list;

static struct spec_info_def spec_info_var;
/* Description of the speculative part of the scheduling.
   If NULL - no speculation.  */
spec_info_t spec_info = NULL;

/* True, if recovery block was added during scheduling of current block.
   Used to determine, if we need to fix INSN_TICKs.  */
static bool haifa_recovery_bb_recently_added_p;

/* True, if recovery block was added during this scheduling pass.
   Used to determine if we should have empty memory pools of dependencies
   after finishing current region.  */
bool haifa_recovery_bb_ever_added_p;

/* Counters of different types of speculative instructions.  */
static int nr_begin_data, nr_be_in_data, nr_begin_control, nr_be_in_control;

/* Array used in {unlink, restore}_bb_notes.  */
static rtx_insn **bb_header = 0;

/* Basic block after which recovery blocks will be created.  */
static basic_block before_recovery;

/* Basic block just before the EXIT_BLOCK and after recovery, if we have
   created it.  */
basic_block after_recovery;

/* FALSE if we add bb to another region, so we don't need to initialize it.  */
bool adding_bb_to_current_region_p = true;

/* Queues, etc.  */

/* An instruction is ready to be scheduled when all insns preceding it
   have already been scheduled.  It is important to ensure that all
   insns which use its result will not be executed until its result
   has been computed.  An insn is maintained in one of four structures:

   (P) the "Pending" set of insns which cannot be scheduled until
   their dependencies have been satisfied.
   (Q) the "Queued" set of insns that can be scheduled when sufficient
   time has passed.
   (R) the "Ready" list of unscheduled, uncommitted insns.
   (S) the "Scheduled" list of insns.

   Initially, all insns are either "Pending" or "Ready" depending on
   whether their dependencies are satisfied.

   Insns move from the "Ready" list to the "Scheduled" list as they
   are committed to the schedule.  As this occurs, the insns in the
   "Pending" list have their dependencies satisfied and move to either
   the "Ready" list or the "Queued" set depending on whether
   sufficient time has passed to make them ready.  As time passes,
   insns move from the "Queued" set to the "Ready" list.

   The "Pending" list (P) are the insns in the INSN_FORW_DEPS of the
   unscheduled insns, i.e., those that are ready, queued, and pending.
   The "Queued" set (Q) is implemented by the variable `insn_queue'.
   The "Ready" list (R) is implemented by the variables `ready' and
   `n_ready'.
   The "Scheduled" list (S) is the new insn chain built by this pass.

   The transition (R->S) is implemented in the scheduling loop in
   `schedule_block' when the best insn to schedule is chosen.
   The transitions (P->R and P->Q) are implemented in `schedule_insn' as
   insns move from the ready list to the scheduled list.
   The transition (Q->R) is implemented in 'queue_to_insn' as time
   passes or stalls are introduced.  */

/* Implement a circular buffer to delay instructions until sufficient
   time has passed.  For the new pipeline description interface,
   MAX_INSN_QUEUE_INDEX is a power of two minus one which is not less
   than maximal time of instruction execution computed by genattr.c on
   the base maximal time of functional unit reservations and getting a
   result.  This is the longest time an insn may be queued.  */

static rtx_insn_list **insn_queue;
static int q_ptr = 0;
static int q_size = 0;
#define NEXT_Q(X) (((X)+1) & max_insn_queue_index)
#define NEXT_Q_AFTER(X, C) (((X)+C) & max_insn_queue_index)

#define QUEUE_SCHEDULED (-3)
#define QUEUE_NOWHERE   (-2)
#define QUEUE_READY     (-1)
/* QUEUE_SCHEDULED - INSN is scheduled.
   QUEUE_NOWHERE   - INSN isn't scheduled yet and is neither in
   queue or ready list.
   QUEUE_READY     - INSN is in ready list.
   N >= 0 - INSN queued for X [where NEXT_Q_AFTER (q_ptr, X) == N] cycles.  */

#define QUEUE_INDEX(INSN) (HID (INSN)->queue_index)

/* The following variable value refers for all current and future
   reservations of the processor units.  */
state_t curr_state;

/* The following variable value is size of memory representing all
   current and future reservations of the processor units.  */
size_t dfa_state_size;

/* The following array is used to find the best insn from ready when
   the automaton pipeline interface is used.  */
signed char *ready_try = NULL;

/* The ready list.  */
struct ready_list ready = {NULL, 0, 0, 0, 0};

/* The pointer to the ready list (to be removed).  */
static struct ready_list *readyp = &ready;

/* Scheduling clock.  */
static int clock_var;

/* Clock at which the previous instruction was issued.  */
static int last_clock_var;

/* Set to true if, when queuing a shadow insn, we discover that it would be
   scheduled too late.  */
static bool must_backtrack;

/* The following variable value is number of essential insns issued on
   the current cycle.  An insn is essential one if it changes the
   processors state.  */
int cycle_issued_insns;

/* This records the actual schedule.  It is built up during the main phase
   of schedule_block, and afterwards used to reorder the insns in the RTL.  */
static vec<rtx_insn *> scheduled_insns;

static int may_trap_exp (const_rtx, int);

/* Nonzero iff the address is comprised from at most 1 register.  */
#define CONST_BASED_ADDRESS_P(x)			\
  (REG_P (x)					\
   || ((GET_CODE (x) == PLUS || GET_CODE (x) == MINUS	\
	|| (GET_CODE (x) == LO_SUM))			\
       && (CONSTANT_P (XEXP (x, 0))			\
	   || CONSTANT_P (XEXP (x, 1)))))

/* Returns a class that insn with GET_DEST(insn)=x may belong to,
   as found by analyzing insn's expression.  */


static int haifa_luid_for_non_insn (rtx x);

/* Haifa version of sched_info hooks common to all headers.  */
const struct common_sched_info_def haifa_common_sched_info =
  {
    NULL, /* fix_recovery_cfg */
    NULL, /* add_block */
    NULL, /* estimate_number_of_insns */
    haifa_luid_for_non_insn, /* luid_for_non_insn */
    SCHED_PASS_UNKNOWN /* sched_pass_id */
  };

/* Mapping from instruction UID to its Logical UID.  */
vec<int> sched_luids;

/* Next LUID to assign to an instruction.  */
int sched_max_luid = 1;

/* Haifa Instruction Data.  */
vec<haifa_insn_data_def> h_i_d;

void (* sched_init_only_bb) (basic_block, basic_block);

/* Split block function.  Different schedulers might use different functions
   to handle their internal data consistent.  */
basic_block (* sched_split_block) (basic_block, rtx);

/* Create empty basic block after the specified block.  */
basic_block (* sched_create_empty_bb) (basic_block);

/* Return the number of cycles until INSN is expected to be ready.
   Return zero if it already is.  */
static int
insn_delay (rtx_insn *insn)
{
  return MAX (INSN_TICK (insn) - clock_var, 0);
}

static int
may_trap_exp (const_rtx x, int is_store)
{
  enum rtx_code code;

  if (x == 0)
    return TRAP_FREE;
  code = GET_CODE (x);
  if (is_store)
    {
      if (code == MEM && may_trap_p (x))
	return TRAP_RISKY;
      else
	return TRAP_FREE;
    }
  if (code == MEM)
    {
      /* The insn uses memory:  a volatile load.  */
      if (MEM_VOLATILE_P (x))
	return IRISKY;
      /* An exception-free load.  */
      if (!may_trap_p (x))
	return IFREE;
      /* A load with 1 base register, to be further checked.  */
      if (CONST_BASED_ADDRESS_P (XEXP (x, 0)))
	return PFREE_CANDIDATE;
      /* No info on the load, to be further checked.  */
      return PRISKY_CANDIDATE;
    }
  else
    {
      const char *fmt;
      int i, insn_class = TRAP_FREE;

      /* Neither store nor load, check if it may cause a trap.  */
      if (may_trap_p (x))
	return TRAP_RISKY;
      /* Recursive step: walk the insn...  */
      fmt = GET_RTX_FORMAT (code);
      for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
	{
	  if (fmt[i] == 'e')
	    {
	      int tmp_class = may_trap_exp (XEXP (x, i), is_store);
	      insn_class = WORST_CLASS (insn_class, tmp_class);
	    }
	  else if (fmt[i] == 'E')
	    {
	      int j;
	      for (j = 0; j < XVECLEN (x, i); j++)
		{
		  int tmp_class = may_trap_exp (XVECEXP (x, i, j), is_store);
		  insn_class = WORST_CLASS (insn_class, tmp_class);
		  if (insn_class == TRAP_RISKY || insn_class == IRISKY)
		    break;
		}
	    }
	  if (insn_class == TRAP_RISKY || insn_class == IRISKY)
	    break;
	}
      return insn_class;
    }
}

/* Classifies rtx X of an insn for the purpose of verifying that X can be
   executed speculatively (and consequently the insn can be moved
   speculatively), by examining X, returning:
   TRAP_RISKY: store, or risky non-load insn (e.g. division by variable).
   TRAP_FREE: non-load insn.
   IFREE: load from a globally safe location.
   IRISKY: volatile load.
   PFREE_CANDIDATE, PRISKY_CANDIDATE: load that need to be checked for
   being either PFREE or PRISKY.  */

static int
haifa_classify_rtx (const_rtx x)
{
  int tmp_class = TRAP_FREE;
  int insn_class = TRAP_FREE;
  enum rtx_code code;

  if (GET_CODE (x) == PARALLEL)
    {
      int i, len = XVECLEN (x, 0);

      for (i = len - 1; i >= 0; i--)
	{
	  tmp_class = haifa_classify_rtx (XVECEXP (x, 0, i));
	  insn_class = WORST_CLASS (insn_class, tmp_class);
	  if (insn_class == TRAP_RISKY || insn_class == IRISKY)
	    break;
	}
    }
  else
    {
      code = GET_CODE (x);
      switch (code)
	{
	case CLOBBER:
	  /* Test if it is a 'store'.  */
	  tmp_class = may_trap_exp (XEXP (x, 0), 1);
	  break;
	case SET:
	  /* Test if it is a store.  */
	  tmp_class = may_trap_exp (SET_DEST (x), 1);
	  if (tmp_class == TRAP_RISKY)
	    break;
	  /* Test if it is a load.  */
	  tmp_class =
	    WORST_CLASS (tmp_class,
			 may_trap_exp (SET_SRC (x), 0));
	  break;
	case COND_EXEC:
	  tmp_class = haifa_classify_rtx (COND_EXEC_CODE (x));
	  if (tmp_class == TRAP_RISKY)
	    break;
	  tmp_class = WORST_CLASS (tmp_class,
				   may_trap_exp (COND_EXEC_TEST (x), 0));
	  break;
	case TRAP_IF:
	  tmp_class = TRAP_RISKY;
	  break;
	default:;
	}
      insn_class = tmp_class;
    }

  return insn_class;
}

int
haifa_classify_insn (const_rtx insn)
{
  return haifa_classify_rtx (PATTERN (insn));
}

/* After the scheduler initialization function has been called, this function
   can be called to enable modulo scheduling.  II is the initiation interval
   we should use, it affects the delays for delay_pairs that were recorded as
   separated by a given number of stages.

   MAX_STAGES provides us with a limit
   after which we give up scheduling; the caller must have unrolled at least
   as many copies of the loop body and recorded delay_pairs for them.
   
   INSNS is the number of real (non-debug) insns in one iteration of
   the loop.  MAX_UID can be used to test whether an insn belongs to
   the first iteration of the loop; all of them have a uid lower than
   MAX_UID.  */
void
set_modulo_params (int ii, int max_stages, int insns, int max_uid)
{
  modulo_ii = ii;
  modulo_max_stages = max_stages;
  modulo_n_insns = insns;
  modulo_iter0_max_uid = max_uid;
  modulo_backtracks_left = param_max_modulo_backtrack_attempts;
}

/* A structure to record a pair of insns where the first one is a real
   insn that has delay slots, and the second is its delayed shadow.
   I1 is scheduled normally and will emit an assembly instruction,
   while I2 describes the side effect that takes place at the
   transition between cycles CYCLES and (CYCLES + 1) after I1.  */
struct delay_pair
{
  struct delay_pair *next_same_i1;
  rtx_insn *i1, *i2;
  int cycles;
  /* When doing modulo scheduling, we a delay_pair can also be used to
     show that I1 and I2 are the same insn in a different stage.  If that
     is the case, STAGES will be nonzero.  */
  int stages;
};

/* Helpers for delay hashing.  */

struct delay_i1_hasher : nofree_ptr_hash <delay_pair>
{
  typedef void *compare_type;
  static inline hashval_t hash (const delay_pair *);
  static inline bool equal (const delay_pair *, const void *);
};

/* Returns a hash value for X, based on hashing just I1.  */

inline hashval_t
delay_i1_hasher::hash (const delay_pair *x)
{
  return htab_hash_pointer (x->i1);
}

/* Return true if I1 of pair X is the same as that of pair Y.  */

inline bool
delay_i1_hasher::equal (const delay_pair *x, const void *y)
{
  return x->i1 == y;
}

struct delay_i2_hasher : free_ptr_hash <delay_pair>
{
  typedef void *compare_type;
  static inline hashval_t hash (const delay_pair *);
  static inline bool equal (const delay_pair *, const void *);
};

/* Returns a hash value for X, based on hashing just I2.  */

inline hashval_t
delay_i2_hasher::hash (const delay_pair *x)
{
  return htab_hash_pointer (x->i2);
}

/* Return true if I2 of pair X is the same as that of pair Y.  */

inline bool
delay_i2_hasher::equal (const delay_pair *x, const void *y)
{
  return x->i2 == y;
}

/* Two hash tables to record delay_pairs, one indexed by I1 and the other
   indexed by I2.  */
static hash_table<delay_i1_hasher> *delay_htab;
static hash_table<delay_i2_hasher> *delay_htab_i2;

/* Called through htab_traverse.  Walk the hashtable using I2 as
   index, and delete all elements involving an UID higher than
   that pointed to by *DATA.  */
int
haifa_htab_i2_traverse (delay_pair **slot, int *data)
{
  int maxuid = *data;
  struct delay_pair *p = *slot;
  if (INSN_UID (p->i2) >= maxuid || INSN_UID (p->i1) >= maxuid)
    {
      delay_htab_i2->clear_slot (slot);
    }
  return 1;
}

/* Called through htab_traverse.  Walk the hashtable using I2 as
   index, and delete all elements involving an UID higher than
   that pointed to by *DATA.  */
int
haifa_htab_i1_traverse (delay_pair **pslot, int *data)
{
  int maxuid = *data;
  struct delay_pair *p, *first, **pprev;

  if (INSN_UID ((*pslot)->i1) >= maxuid)
    {
      delay_htab->clear_slot (pslot);
      return 1;
    }
  pprev = &first;
  for (p = *pslot; p; p = p->next_same_i1)
    {
      if (INSN_UID (p->i2) < maxuid)
	{
	  *pprev = p;
	  pprev = &p->next_same_i1;
	}
    }
  *pprev = NULL;
  if (first == NULL)
    delay_htab->clear_slot (pslot);
  else
    *pslot = first;
  return 1;
}

/* Discard all delay pairs which involve an insn with an UID higher
   than MAX_UID.  */
void
discard_delay_pairs_above (int max_uid)
{
  delay_htab->traverse <int *, haifa_htab_i1_traverse> (&max_uid);
  delay_htab_i2->traverse <int *, haifa_htab_i2_traverse> (&max_uid);
}

/* This function can be called by a port just before it starts the final
   scheduling pass.  It records the fact that an instruction with delay
   slots has been split into two insns, I1 and I2.  The first one will be
   scheduled normally and initiates the operation.  The second one is a
   shadow which must follow a specific number of cycles after I1; its only
   purpose is to show the side effect that occurs at that cycle in the RTL.
   If a JUMP_INSN or a CALL_INSN has been split, I1 should be a normal INSN,
   while I2 retains the original insn type.

   There are two ways in which the number of cycles can be specified,
   involving the CYCLES and STAGES arguments to this function.  If STAGES
   is zero, we just use the value of CYCLES.  Otherwise, STAGES is a factor
   which is multiplied by MODULO_II to give the number of cycles.  This is
   only useful if the caller also calls set_modulo_params to enable modulo
   scheduling.  */

void
record_delay_slot_pair (rtx_insn *i1, rtx_insn *i2, int cycles, int stages)
{
  struct delay_pair *p = XNEW (struct delay_pair);
  struct delay_pair **slot;

  p->i1 = i1;
  p->i2 = i2;
  p->cycles = cycles;
  p->stages = stages;

  if (!delay_htab)
    {
      delay_htab = new hash_table<delay_i1_hasher> (10);
      delay_htab_i2 = new hash_table<delay_i2_hasher> (10);
    }
  slot = delay_htab->find_slot_with_hash (i1, htab_hash_pointer (i1), INSERT);
  p->next_same_i1 = *slot;
  *slot = p;
  slot = delay_htab_i2->find_slot (p, INSERT);
  *slot = p;
}

/* Examine the delay pair hashtable to see if INSN is a shadow for another,
   and return the other insn if so.  Return NULL otherwise.  */
rtx_insn *
real_insn_for_shadow (rtx_insn *insn)
{
  struct delay_pair *pair;

  if (!delay_htab)
    return NULL;

  pair = delay_htab_i2->find_with_hash (insn, htab_hash_pointer (insn));
  if (!pair || pair->stages > 0)
    return NULL;
  return pair->i1;
}

/* For a pair P of insns, return the fixed distance in cycles from the first
   insn after which the second must be scheduled.  */
static int
pair_delay (struct delay_pair *p)
{
  if (p->stages == 0)
    return p->cycles;
  else
    return p->stages * modulo_ii;
}

/* Given an insn INSN, add a dependence on its delayed shadow if it
   has one.  Also try to find situations where shadows depend on each other
   and add dependencies to the real insns to limit the amount of backtracking
   needed.  */
void
add_delay_dependencies (rtx_insn *insn)
{
  struct delay_pair *pair;
  sd_iterator_def sd_it;
  dep_t dep;

  if (!delay_htab)
    return;

  pair = delay_htab_i2->find_with_hash (insn, htab_hash_pointer (insn));
  if (!pair)
    return;
  add_dependence (insn, pair->i1, REG_DEP_ANTI);
  if (pair->stages)
    return;

  FOR_EACH_DEP (pair->i2, SD_LIST_BACK, sd_it, dep)
    {
      rtx_insn *pro = DEP_PRO (dep);
      struct delay_pair *other_pair
	= delay_htab_i2->find_with_hash (pro, htab_hash_pointer (pro));
      if (!other_pair || other_pair->stages)
	continue;
      if (pair_delay (other_pair) >= pair_delay (pair))
	{
	  if (sched_verbose >= 4)
	    {
	      fprintf (sched_dump, ";;\tadding dependence %d <- %d\n",
		       INSN_UID (other_pair->i1),
		       INSN_UID (pair->i1));
	      fprintf (sched_dump, ";;\tpair1 %d <- %d, cost %d\n",
		       INSN_UID (pair->i1),
		       INSN_UID (pair->i2),
		       pair_delay (pair));
	      fprintf (sched_dump, ";;\tpair2 %d <- %d, cost %d\n",
		       INSN_UID (other_pair->i1),
		       INSN_UID (other_pair->i2),
		       pair_delay (other_pair));
	    }
	  add_dependence (pair->i1, other_pair->i1, REG_DEP_ANTI);
	}
    }
}

/* Forward declarations.  */

static int priority (rtx_insn *, bool force_recompute = false);
static int autopref_rank_for_schedule (const rtx_insn *, const rtx_insn *);
static int rank_for_schedule (const void *, const void *);
static void swap_sort (rtx_insn **, int);
static void queue_insn (rtx_insn *, int, const char *);
static int schedule_insn (rtx_insn *);
static void adjust_priority (rtx_insn *);
static void advance_one_cycle (void);
static void extend_h_i_d (void);


/* Notes handling mechanism:
   =========================
   Generally, NOTES are saved before scheduling and restored after scheduling.
   The scheduler distinguishes between two types of notes:

   (1) LOOP_BEGIN, LOOP_END, SETJMP, EHREGION_BEG, EHREGION_END notes:
   Before scheduling a region, a pointer to the note is added to the insn
   that follows or precedes it.  (This happens as part of the data dependence
   computation).  After scheduling an insn, the pointer contained in it is
   used for regenerating the corresponding note (in reemit_notes).

   (2) All other notes (e.g. INSN_DELETED):  Before scheduling a block,
   these notes are put in a list (in rm_other_notes() and
   unlink_other_notes ()).  After scheduling the block, these notes are
   inserted at the beginning of the block (in schedule_block()).  */

static void ready_add (struct ready_list *, rtx_insn *, bool);
static rtx_insn *ready_remove_first (struct ready_list *);
static rtx_insn *ready_remove_first_dispatch (struct ready_list *ready);

static void queue_to_ready (struct ready_list *);
static int early_queue_to_ready (state_t, struct ready_list *);

/* The following functions are used to implement multi-pass scheduling
   on the first cycle.  */
static rtx_insn *ready_remove (struct ready_list *, int);
static void ready_remove_insn (rtx_insn *);

static void fix_inter_tick (rtx_insn *, rtx_insn *);
static int fix_tick_ready (rtx_insn *);
static void change_queue_index (rtx_insn *, int);

/* The following functions are used to implement scheduling of data/control
   speculative instructions.  */

static void extend_h_i_d (void);
static void init_h_i_d (rtx_insn *);
static int haifa_speculate_insn (rtx_insn *, ds_t, rtx *);
static void generate_recovery_code (rtx_insn *);
static void process_insn_forw_deps_be_in_spec (rtx_insn *, rtx_insn *, ds_t);
static void begin_speculative_block (rtx_insn *);
static void add_to_speculative_block (rtx_insn *);
static void init_before_recovery (basic_block *);
static void create_check_block_twin (rtx_insn *, bool);
static void fix_recovery_deps (basic_block);
static bool haifa_change_pattern (rtx_insn *, rtx);
static void dump_new_block_header (int, basic_block, rtx_insn *, rtx_insn *);
static void restore_bb_notes (basic_block);
static void fix_jump_move (rtx_insn *);
static void move_block_after_check (rtx_insn *);
static void move_succs (vec<edge, va_gc> **, basic_block);
static void sched_remove_insn (rtx_insn *);
static void clear_priorities (rtx_insn *, rtx_vec_t *);
static void calc_priorities (rtx_vec_t);
static void add_jump_dependencies (rtx_insn *, rtx_insn *);

#endif /* INSN_SCHEDULING */

/* Point to state used for the current scheduling pass.  */
struct haifa_sched_info *current_sched_info;

#ifndef INSN_SCHEDULING
void
schedule_insns (void)
{
}
#else

/* Do register pressure sensitive insn scheduling if the flag is set
   up.  */
enum sched_pressure_algorithm sched_pressure;

/* Map regno -> its pressure class.  The map defined only when
   SCHED_PRESSURE != SCHED_PRESSURE_NONE.  */
enum reg_class *sched_regno_pressure_class;

/* The current register pressure.  Only elements corresponding pressure
   classes are defined.  */
static int curr_reg_pressure[N_REG_CLASSES];

/* Saved value of the previous array.  */
static int saved_reg_pressure[N_REG_CLASSES];

/* Register living at given scheduling point.  */
static bitmap curr_reg_live;

/* Saved value of the previous array.  */
static bitmap saved_reg_live;

/* Registers mentioned in the current region.  */
static bitmap region_ref_regs;

/* Temporary bitmap used for SCHED_PRESSURE_MODEL.  */
static bitmap tmp_bitmap;

/* Effective number of available registers of a given class (see comment
   in sched_pressure_start_bb).  */
static int sched_class_regs_num[N_REG_CLASSES];
/* The number of registers that the function would need to save before it
   uses them, and the number of fixed_regs.  Helpers for calculating of
   sched_class_regs_num.  */
static int call_saved_regs_num[N_REG_CLASSES];
static int fixed_regs_num[N_REG_CLASSES];

/* Initiate register pressure relative info for scheduling the current
   region.  Currently it is only clearing register mentioned in the
   current region.  */
void
sched_init_region_reg_pressure_info (void)
{
  bitmap_clear (region_ref_regs);
}

/* PRESSURE[CL] describes the pressure on register class CL.  Update it
   for the birth (if BIRTH_P) or death (if !BIRTH_P) of register REGNO.
   LIVE tracks the set of live registers; if it is null, assume that
   every birth or death is genuine.  */
static inline void
mark_regno_birth_or_death (bitmap live, int *pressure, int regno, bool birth_p)
{
  enum reg_class pressure_class;

  pressure_class = sched_regno_pressure_class[regno];
  if (regno >= FIRST_PSEUDO_REGISTER)
    {
      if (pressure_class != NO_REGS)
	{
	  if (birth_p)
	    {
	      if (!live || bitmap_set_bit (live, regno))
		pressure[pressure_class]
		  += (ira_reg_class_max_nregs
		      [pressure_class][PSEUDO_REGNO_MODE (regno)]);
	    }
	  else
	    {
	      if (!live || bitmap_clear_bit (live, regno))
		pressure[pressure_class]
		  -= (ira_reg_class_max_nregs
		      [pressure_class][PSEUDO_REGNO_MODE (regno)]);
	    }
	}
    }
  else if (pressure_class != NO_REGS
	   && ! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno))
    {
      if (birth_p)
	{
	  if (!live || bitmap_set_bit (live, regno))
	    pressure[pressure_class]++;
	}
      else
	{
	  if (!live || bitmap_clear_bit (live, regno))
	    pressure[pressure_class]--;
	}
    }
}

/* Initiate current register pressure related info from living
   registers given by LIVE.  */
static void
initiate_reg_pressure_info (bitmap live)
{
  int i;
  unsigned int j;
  bitmap_iterator bi;

  for (i = 0; i < ira_pressure_classes_num; i++)
    curr_reg_pressure[ira_pressure_classes[i]] = 0;
  bitmap_clear (curr_reg_live);
  EXECUTE_IF_SET_IN_BITMAP (live, 0, j, bi)
    if (sched_pressure == SCHED_PRESSURE_MODEL
	|| current_nr_blocks == 1
	|| bitmap_bit_p (region_ref_regs, j))
      mark_regno_birth_or_death (curr_reg_live, curr_reg_pressure, j, true);
}

/* Mark registers in X as mentioned in the current region.  */
static void
setup_ref_regs (rtx x)
{
  int i, j;
  const RTX_CODE code = GET_CODE (x);
  const char *fmt;

  if (REG_P (x))
    {
      bitmap_set_range (region_ref_regs, REGNO (x), REG_NREGS (x));
      return;
    }
  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    if (fmt[i] == 'e')
      setup_ref_regs (XEXP (x, i));
    else if (fmt[i] == 'E')
      {
	for (j = 0; j < XVECLEN (x, i); j++)
	  setup_ref_regs (XVECEXP (x, i, j));
      }
}

/* Initiate current register pressure related info at the start of
   basic block BB.  */
static void
initiate_bb_reg_pressure_info (basic_block bb)
{
  unsigned int i ATTRIBUTE_UNUSED;
  rtx_insn *insn;

  if (current_nr_blocks > 1)
    FOR_BB_INSNS (bb, insn)
      if (NONDEBUG_INSN_P (insn))
	setup_ref_regs (PATTERN (insn));
  initiate_reg_pressure_info (df_get_live_in (bb));
  if (bb_has_eh_pred (bb))
    for (i = 0; ; ++i)
      {
	unsigned int regno = EH_RETURN_DATA_REGNO (i);

	if (regno == INVALID_REGNUM)
	  break;
	if (! bitmap_bit_p (df_get_live_in (bb), regno))
	  mark_regno_birth_or_death (curr_reg_live, curr_reg_pressure,
				     regno, true);
      }
}

/* Save current register pressure related info.  */
static void
save_reg_pressure (void)
{
  int i;

  for (i = 0; i < ira_pressure_classes_num; i++)
    saved_reg_pressure[ira_pressure_classes[i]]
      = curr_reg_pressure[ira_pressure_classes[i]];
  bitmap_copy (saved_reg_live, curr_reg_live);
}

/* Restore saved register pressure related info.  */
static void
restore_reg_pressure (void)
{
  int i;

  for (i = 0; i < ira_pressure_classes_num; i++)
    curr_reg_pressure[ira_pressure_classes[i]]
      = saved_reg_pressure[ira_pressure_classes[i]];
  bitmap_copy (curr_reg_live, saved_reg_live);
}

/* Return TRUE if the register is dying after its USE.  */
static bool
dying_use_p (struct reg_use_data *use)
{
  struct reg_use_data *next;

  for (next = use->next_regno_use; next != use; next = next->next_regno_use)
    if (NONDEBUG_INSN_P (next->insn)
	&& QUEUE_INDEX (next->insn) != QUEUE_SCHEDULED)
      return false;
  return true;
}

/* Print info about the current register pressure and its excess for
   each pressure class.  */
static void
print_curr_reg_pressure (void)
{
  int i;
  enum reg_class cl;

  fprintf (sched_dump, ";;\t");
  for (i = 0; i < ira_pressure_classes_num; i++)
    {
      cl = ira_pressure_classes[i];
      gcc_assert (curr_reg_pressure[cl] >= 0);
      fprintf (sched_dump, "  %s:%d(%d)", reg_class_names[cl],
	       curr_reg_pressure[cl],
	       curr_reg_pressure[cl] - sched_class_regs_num[cl]);
    }
  fprintf (sched_dump, "\n");
}

/* Determine if INSN has a condition that is clobbered if a register
   in SET_REGS is modified.  */
static bool
cond_clobbered_p (rtx_insn *insn, HARD_REG_SET set_regs)
{
  rtx pat = PATTERN (insn);
  gcc_assert (GET_CODE (pat) == COND_EXEC);
  if (TEST_HARD_REG_BIT (set_regs, REGNO (XEXP (COND_EXEC_TEST (pat), 0))))
    {
      sd_iterator_def sd_it;
      dep_t dep;
      haifa_change_pattern (insn, ORIG_PAT (insn));
      FOR_EACH_DEP (insn, SD_LIST_BACK, sd_it, dep)
	DEP_STATUS (dep) &= ~DEP_CANCELLED;
      TODO_SPEC (insn) = HARD_DEP;
      if (sched_verbose >= 2)
	fprintf (sched_dump,
		 ";;\t\tdequeue insn %s because of clobbered condition\n",
		 (*current_sched_info->print_insn) (insn, 0));
      return true;
    }

  return false;
}

/* This function should be called after modifying the pattern of INSN,
   to update scheduler data structures as needed.  */
static void
update_insn_after_change (rtx_insn *insn)
{
  sd_iterator_def sd_it;
  dep_t dep;

  dfa_clear_single_insn_cache (insn);

  sd_it = sd_iterator_start (insn,
			     SD_LIST_FORW | SD_LIST_BACK | SD_LIST_RES_BACK);
  while (sd_iterator_cond (&sd_it, &dep))
    {
      DEP_COST (dep) = UNKNOWN_DEP_COST;
      sd_iterator_next (&sd_it);
    }

  /* Invalidate INSN_COST, so it'll be recalculated.  */
  INSN_COST (insn) = -1;
  /* Invalidate INSN_TICK, so it'll be recalculated.  */
  INSN_TICK (insn) = INVALID_TICK;

  /* Invalidate autoprefetch data entry.  */
  INSN_AUTOPREF_MULTIPASS_DATA (insn)[0].status
    = AUTOPREF_MULTIPASS_DATA_UNINITIALIZED;
  INSN_AUTOPREF_MULTIPASS_DATA (insn)[1].status
    = AUTOPREF_MULTIPASS_DATA_UNINITIALIZED;
}


/* Two VECs, one to hold dependencies for which pattern replacements
   need to be applied or restored at the start of the next cycle, and
   another to hold an integer that is either one, to apply the
   corresponding replacement, or zero to restore it.  */
static vec<dep_t> next_cycle_replace_deps;
static vec<int> next_cycle_apply;

static void apply_replacement (dep_t, bool);
static void restore_pattern (dep_t, bool);

/* Look at the remaining dependencies for insn NEXT, and compute and return
   the TODO_SPEC value we should use for it.  This is called after one of
   NEXT's dependencies has been resolved.
   We also perform pattern replacements for predication, and for broken
   replacement dependencies.  The latter is only done if FOR_BACKTRACK is
   false.  */

static ds_t
recompute_todo_spec (rtx_insn *next, bool for_backtrack)
{
  ds_t new_ds;
  sd_iterator_def sd_it;
  dep_t dep, modify_dep = NULL;
  int n_spec = 0;
  int n_control = 0;
  int n_replace = 0;
  bool first_p = true;

  if (sd_lists_empty_p (next, SD_LIST_BACK))
    /* NEXT has all its dependencies resolved.  */
    return 0;

  if (!sd_lists_empty_p (next, SD_LIST_HARD_BACK))
    return HARD_DEP;

  /* If NEXT is intended to sit adjacent to this instruction, we don't
     want to try to break any dependencies.  Treat it as a HARD_DEP.  */
  if (SCHED_GROUP_P (next))
    return HARD_DEP;

  /* Now we've got NEXT with speculative deps only.
     1. Look at the deps to see what we have to do.
     2. Check if we can do 'todo'.  */
  new_ds = 0;

  FOR_EACH_DEP (next, SD_LIST_BACK, sd_it, dep)
    {
      rtx_insn *pro = DEP_PRO (dep);
      ds_t ds = DEP_STATUS (dep) & SPECULATIVE;

      if (DEBUG_INSN_P (pro) && !DEBUG_INSN_P (next))
	continue;

      if (ds)
	{
	  n_spec++;
	  if (first_p)
	    {
	      first_p = false;

	      new_ds = ds;
	    }
	  else
	    new_ds = ds_merge (new_ds, ds);
	}
      else if (DEP_TYPE (dep) == REG_DEP_CONTROL)
	{
	  if (QUEUE_INDEX (pro) != QUEUE_SCHEDULED)
	    {
	      n_control++;
	      modify_dep = dep;
	    }
	  DEP_STATUS (dep) &= ~DEP_CANCELLED;
	}
      else if (DEP_REPLACE (dep) != NULL)
	{
	  if (QUEUE_INDEX (pro) != QUEUE_SCHEDULED)
	    {
	      n_replace++;
	      modify_dep = dep;
	    }
	  DEP_STATUS (dep) &= ~DEP_CANCELLED;
	}
    }

  if (n_replace > 0 && n_control == 0 && n_spec == 0)
    {
      if (!dbg_cnt (sched_breakdep))
	return HARD_DEP;
      FOR_EACH_DEP (next, SD_LIST_BACK, sd_it, dep)
	{
	  struct dep_replacement *desc = DEP_REPLACE (dep);
	  if (desc != NULL)
	    {
	      if (desc->insn == next && !for_backtrack)
		{
		  gcc_assert (n_replace == 1);
		  apply_replacement (dep, true);
		}
	      DEP_STATUS (dep) |= DEP_CANCELLED;
	    }
	}
      return 0;
    }
  
  else if (n_control == 1 && n_replace == 0 && n_spec == 0)
    {
      rtx_insn *pro, *other;
      rtx new_pat;
      rtx cond = NULL_RTX;
      bool success;
      rtx_insn *prev = NULL;
      int i;
      unsigned regno;
  
      if ((current_sched_info->flags & DO_PREDICATION) == 0
	  || (ORIG_PAT (next) != NULL_RTX
	      && PREDICATED_PAT (next) == NULL_RTX))
	return HARD_DEP;

      pro = DEP_PRO (modify_dep);
      other = real_insn_for_shadow (pro);
      if (other != NULL_RTX)
	pro = other;

      cond = sched_get_reverse_condition_uncached (pro);
      regno = REGNO (XEXP (cond, 0));

      /* Find the last scheduled insn that modifies the condition register.
	 We can stop looking once we find the insn we depend on through the
	 REG_DEP_CONTROL; if the condition register isn't modified after it,
	 we know that it still has the right value.  */
      if (QUEUE_INDEX (pro) == QUEUE_SCHEDULED)
	FOR_EACH_VEC_ELT_REVERSE (scheduled_insns, i, prev)
	  {
	    HARD_REG_SET t;

	    find_all_hard_reg_sets (prev, &t, true);
	    if (TEST_HARD_REG_BIT (t, regno))
	      return HARD_DEP;
	    if (prev == pro)
	      break;
	  }
      if (ORIG_PAT (next) == NULL_RTX)
	{
	  ORIG_PAT (next) = PATTERN (next);

	  new_pat = gen_rtx_COND_EXEC (VOIDmode, cond, PATTERN (next));
	  success = haifa_change_pattern (next, new_pat);
	  if (!success)
	    return HARD_DEP;
	  PREDICATED_PAT (next) = new_pat;
	}
      else if (PATTERN (next) != PREDICATED_PAT (next))
	{
	  bool success = haifa_change_pattern (next,
					       PREDICATED_PAT (next));
	  gcc_assert (success);
	}
      DEP_STATUS (modify_dep) |= DEP_CANCELLED;
      return DEP_CONTROL;
    }

  if (PREDICATED_PAT (next) != NULL_RTX)
    {
      int tick = INSN_TICK (next);
      bool success = haifa_change_pattern (next,
					   ORIG_PAT (next));
      INSN_TICK (next) = tick;
      gcc_assert (success);
    }

  /* We can't handle the case where there are both speculative and control
     dependencies, so we return HARD_DEP in such a case.  Also fail if
     we have speculative dependencies with not enough points, or more than
     one control dependency.  */
  if ((n_spec > 0 && (n_control > 0 || n_replace > 0))
      || (n_spec > 0
	  /* Too few points?  */
	  && ds_weak (new_ds) < spec_info->data_weakness_cutoff)
      || n_control > 0
      || n_replace > 0)
    return HARD_DEP;

  return new_ds;
}

/* Pointer to the last instruction scheduled.  */
static rtx_insn *last_scheduled_insn;

/* Pointer to the last nondebug instruction scheduled within the
   block, or the prev_head of the scheduling block.  Used by
   rank_for_schedule, so that insns independent of the last scheduled
   insn will be preferred over dependent instructions.  */
static rtx_insn *last_nondebug_scheduled_insn;

/* Pointer that iterates through the list of unscheduled insns if we
   have a dbg_cnt enabled.  It always points at an insn prior to the
   first unscheduled one.  */
static rtx_insn *nonscheduled_insns_begin;

/* Compute cost of executing INSN.
   This is the number of cycles between instruction issue and
   instruction results.  */
int
insn_sched_cost (rtx_insn *insn)
{
  int cost;

  if (sched_fusion)
    return 0;

  if (sel_sched_p ())
    {
      if (recog_memoized (insn) < 0)
	return 0;

      cost = insn_default_latency (insn);
      if (cost < 0)
	cost = 0;

      return cost;
    }

  cost = INSN_COST (insn);

  if (cost < 0)
    {
      /* A USE insn, or something else we don't need to
	 understand.  We can't pass these directly to
	 result_ready_cost or insn_default_latency because it will
	 trigger a fatal error for unrecognizable insns.  */
      if (recog_memoized (insn) < 0)
	{
	  INSN_COST (insn) = 0;
	  return 0;
	}
      else
	{
	  cost = insn_default_latency (insn);
	  if (cost < 0)
	    cost = 0;

	  INSN_COST (insn) = cost;
	}
    }

  return cost;
}

/* Compute cost of dependence LINK.
   This is the number of cycles between instruction issue and
   instruction results.
   ??? We also use this function to call recog_memoized on all insns.  */
int
dep_cost_1 (dep_t link, dw_t dw)
{
  rtx_insn *insn = DEP_PRO (link);
  rtx_insn *used = DEP_CON (link);
  int cost;

  if (DEP_COST (link) != UNKNOWN_DEP_COST)
    return DEP_COST (link);

  if (delay_htab)
    {
      struct delay_pair *delay_entry;
      delay_entry
	= delay_htab_i2->find_with_hash (used, htab_hash_pointer (used));
      if (delay_entry)
	{
	  if (delay_entry->i1 == insn)
	    {
	      DEP_COST (link) = pair_delay (delay_entry);
	      return DEP_COST (link);
	    }
	}
    }

  /* A USE insn should never require the value used to be computed.
     This allows the computation of a function's result and parameter
     values to overlap the return and call.  We don't care about the
     dependence cost when only decreasing register pressure.  */
  if (recog_memoized (used) < 0)
    {
      cost = 0;
      recog_memoized (insn);
    }
  else
    {
      enum reg_note dep_type = DEP_TYPE (link);

      cost = insn_sched_cost (insn);

      if (INSN_CODE (insn) >= 0)
	{
	  if (dep_type == REG_DEP_ANTI)
	    cost = 0;
	  else if (dep_type == REG_DEP_OUTPUT)
	    {
	      cost = (insn_default_latency (insn)
		      - insn_default_latency (used));
	      if (cost <= 0)
		cost = 1;
	    }
	  else if (bypass_p (insn))
	    cost = insn_latency (insn, used);
	}


      if (targetm.sched.adjust_cost)
	cost = targetm.sched.adjust_cost (used, (int) dep_type, insn, cost,
					  dw);

      if (cost < 0)
	cost = 0;
    }

  DEP_COST (link) = cost;
  return cost;
}

/* Compute cost of dependence LINK.
   This is the number of cycles between instruction issue and
   instruction results.  */
int
dep_cost (dep_t link)
{
  return dep_cost_1 (link, 0);
}

/* Use this sel-sched.c friendly function in reorder2 instead of increasing
   INSN_PRIORITY explicitly.  */
void
increase_insn_priority (rtx_insn *insn, int amount)
{
  if (!sel_sched_p ())
    {
      /* We're dealing with haifa-sched.c INSN_PRIORITY.  */
      if (INSN_PRIORITY_KNOWN (insn))
	  INSN_PRIORITY (insn) += amount;
    }
  else
    {
      /* In sel-sched.c INSN_PRIORITY is not kept up to date.
	 Use EXPR_PRIORITY instead. */
      sel_add_to_insn_priority (insn, amount);
    }
}

/* Return 'true' if DEP should be included in priority calculations.  */
static bool
contributes_to_priority_p (dep_t dep)
{
  if (DEBUG_INSN_P (DEP_CON (dep))
      || DEBUG_INSN_P (DEP_PRO (dep)))
    return false;

  /* Critical path is meaningful in block boundaries only.  */
  if (!current_sched_info->contributes_to_priority (DEP_CON (dep),
						    DEP_PRO (dep)))
    return false;

  if (DEP_REPLACE (dep) != NULL)
    return false;

  /* If flag COUNT_SPEC_IN_CRITICAL_PATH is set,
     then speculative instructions will less likely be
     scheduled.  That is because the priority of
     their producers will increase, and, thus, the
     producers will more likely be scheduled, thus,
     resolving the dependence.  */
  if (sched_deps_info->generate_spec_deps
      && !(spec_info->flags & COUNT_SPEC_IN_CRITICAL_PATH)
      && (DEP_STATUS (dep) & SPECULATIVE))
    return false;

  return true;
}

/* Compute the number of nondebug deps in list LIST for INSN.  */

static int
dep_list_size (rtx_insn *insn, sd_list_types_def list)
{
  sd_iterator_def sd_it;
  dep_t dep;
  int dbgcount = 0, nodbgcount = 0;

  if (!MAY_HAVE_DEBUG_INSNS)
    return sd_lists_size (insn, list);

  FOR_EACH_DEP (insn, list, sd_it, dep)
    {
      if (DEBUG_INSN_P (DEP_CON (dep)))
	dbgcount++;
      else if (!DEBUG_INSN_P (DEP_PRO (dep)))
	nodbgcount++;
    }

  gcc_assert (dbgcount + nodbgcount == sd_lists_size (insn, list));

  return nodbgcount;
}

bool sched_fusion;

/* Compute the priority number for INSN.  */
static int
priority (rtx_insn *insn, bool force_recompute)
{
  if (! INSN_P (insn))
    return 0;

  /* We should not be interested in priority of an already scheduled insn.  */
  gcc_assert (QUEUE_INDEX (insn) != QUEUE_SCHEDULED);

  if (force_recompute || !INSN_PRIORITY_KNOWN (insn))
    {
      int this_priority = -1;

      if (sched_fusion)
	{
	  int this_fusion_priority;

	  targetm.sched.fusion_priority (insn, FUSION_MAX_PRIORITY,
					 &this_fusion_priority, &this_priority);
	  INSN_FUSION_PRIORITY (insn) = this_fusion_priority;
	}
      else if (dep_list_size (insn, SD_LIST_FORW) == 0)
	/* ??? We should set INSN_PRIORITY to insn_sched_cost when and insn
	   has some forward deps but all of them are ignored by
	   contributes_to_priority hook.  At the moment we set priority of
	   such insn to 0.  */
	this_priority = insn_sched_cost (insn);
      else
	{
	  rtx_insn *prev_first, *twin;
	  basic_block rec;

	  /* For recovery check instructions we calculate priority slightly
	     different than that of normal instructions.  Instead of walking
	     through INSN_FORW_DEPS (check) list, we walk through
	     INSN_FORW_DEPS list of each instruction in the corresponding
	     recovery block.  */

          /* Selective scheduling does not define RECOVERY_BLOCK macro.  */
	  rec = sel_sched_p () ? NULL : RECOVERY_BLOCK (insn);
	  if (!rec || rec == EXIT_BLOCK_PTR_FOR_FN (cfun))
	    {
	      prev_first = PREV_INSN (insn);
	      twin = insn;
	    }
	  else
	    {
	      prev_first = NEXT_INSN (BB_HEAD (rec));
	      twin = PREV_INSN (BB_END (rec));
	    }

	  do
	    {
	      sd_iterator_def sd_it;
	      dep_t dep;

	      FOR_EACH_DEP (twin, SD_LIST_FORW, sd_it, dep)
		{
		  rtx_insn *next;
		  int next_priority;

		  next = DEP_CON (dep);

		  if (BLOCK_FOR_INSN (next) != rec)
		    {
		      int cost;

		      if (!contributes_to_priority_p (dep))
			continue;

		      if (twin == insn)
			cost = dep_cost (dep);
		      else
			{
			  struct _dep _dep1, *dep1 = &_dep1;

			  init_dep (dep1, insn, next, REG_DEP_ANTI);

			  cost = dep_cost (dep1);
			}

		      next_priority = cost + priority (next);

		      if (next_priority > this_priority)
			this_priority = next_priority;
		    }
		}

	      twin = PREV_INSN (twin);
	    }
	  while (twin != prev_first);
	}

      if (this_priority < 0)
	{
	  gcc_assert (this_priority == -1);

	  this_priority = insn_sched_cost (insn);
	}

      INSN_PRIORITY (insn) = this_priority;
      INSN_PRIORITY_STATUS (insn) = 1;
    }

  return INSN_PRIORITY (insn);
}

/* Macros and functions for keeping the priority queue sorted, and
   dealing with queuing and dequeuing of instructions.  */

/* For each pressure class CL, set DEATH[CL] to the number of registers
   in that class that die in INSN.  */

static void
calculate_reg_deaths (rtx_insn *insn, int *death)
{
  int i;
  struct reg_use_data *use;

  for (i = 0; i < ira_pressure_classes_num; i++)
    death[ira_pressure_classes[i]] = 0;
  for (use = INSN_REG_USE_LIST (insn); use != NULL; use = use->next_insn_use)
    if (dying_use_p (use))
      mark_regno_birth_or_death (0, death, use->regno, true);
}

/* Setup info about the current register pressure impact of scheduling
   INSN at the current scheduling point.  */
static void
setup_insn_reg_pressure_info (rtx_insn *insn)
{
  int i, change, before, after, hard_regno;
  int excess_cost_change;
  machine_mode mode;
  enum reg_class cl;
  struct reg_pressure_data *pressure_info;
  int *max_reg_pressure;
  static int death[N_REG_CLASSES];

  gcc_checking_assert (!DEBUG_INSN_P (insn));

  excess_cost_change = 0;
  calculate_reg_deaths (insn, death);
  pressure_info = INSN_REG_PRESSURE (insn);
  max_reg_pressure = INSN_MAX_REG_PRESSURE (insn);
  gcc_assert (pressure_info != NULL && max_reg_pressure != NULL);
  for (i = 0; i < ira_pressure_classes_num; i++)
    {
      cl = ira_pressure_classes[i];
      gcc_assert (curr_reg_pressure[cl] >= 0);
      change = (int) pressure_info[i].set_increase - death[cl];
      before = MAX (0, max_reg_pressure[i] - sched_class_regs_num[cl]);
      after = MAX (0, max_reg_pressure[i] + change
		   - sched_class_regs_num[cl]);
      hard_regno = ira_class_hard_regs[cl][0];
      gcc_assert (hard_regno >= 0);
      mode = reg_raw_mode[hard_regno];
      excess_cost_change += ((after - before)
			     * (ira_memory_move_cost[mode][cl][0]
				+ ira_memory_move_cost[mode][cl][1]));
    }
  INSN_REG_PRESSURE_EXCESS_COST_CHANGE (insn) = excess_cost_change;
}

/* This is the first page of code related to SCHED_PRESSURE_MODEL.
   It tries to make the scheduler take register pressure into account
   without introducing too many unnecessary stalls.  It hooks into the
   main scheduling algorithm at several points:

    - Before scheduling starts, model_start_schedule constructs a
      "model schedule" for the current block.  This model schedule is
      chosen solely to keep register pressure down.  It does not take the
      target's pipeline or the original instruction order into account,
      except as a tie-breaker.  It also doesn't work to a particular
      pressure limit.

      This model schedule gives us an idea of what pressure can be
      achieved for the block and gives us an example of a schedule that
      keeps to that pressure.  It also makes the final schedule less
      dependent on the original instruction order.  This is important
      because the original order can either be "wide" (many values live
      at once, such as in user-scheduled code) or "narrow" (few values
      live at once, such as after loop unrolling, where several
      iterations are executed sequentially).

      We do not apply this model schedule to the rtx stream.  We simply
      record it in model_schedule.  We also compute the maximum pressure,
      MP, that was seen during this schedule.

    - Instructions are added to the ready queue even if they require
      a stall.  The length of the stall is instead computed as:

	 MAX (INSN_TICK (INSN) - clock_var, 0)

      (= insn_delay).  This allows rank_for_schedule to choose between
      introducing a deliberate stall or increasing pressure.

    - Before sorting the ready queue, model_set_excess_costs assigns
      a pressure-based cost to each ready instruction in the queue.
      This is the instruction's INSN_REG_PRESSURE_EXCESS_COST_CHANGE
      (ECC for short) and is effectively measured in cycles.

    - rank_for_schedule ranks instructions based on:

	ECC (insn) + insn_delay (insn)

      then as:

	insn_delay (insn)

      So, for example, an instruction X1 with an ECC of 1 that can issue
      now will win over an instruction X0 with an ECC of zero that would
      introduce a stall of one cycle.  However, an instruction X2 with an
      ECC of 2 that can issue now will lose to both X0 and X1.

    - When an instruction is scheduled, model_recompute updates the model
      schedule with the new pressures (some of which might now exceed the
      original maximum pressure MP).  model_update_limit_points then searches
      for the new point of maximum pressure, if not already known.  */

/* Used to separate high-verbosity debug information for SCHED_PRESSURE_MODEL
   from surrounding debug information.  */
#define MODEL_BAR \
  ";;\t\t+------------------------------------------------------\n"

/* Information about the pressure on a particular register class at a
   particular point of the model schedule.  */
struct model_pressure_data {
  /* The pressure at this point of the model schedule, or -1 if the
     point is associated with an instruction that has already been
     scheduled.  */
  int ref_pressure;

  /* The maximum pressure during or after this point of the model schedule.  */
  int max_pressure;
};

/* Per-instruction information that is used while building the model
   schedule.  Here, "schedule" refers to the model schedule rather
   than the main schedule.  */
struct model_insn_info {
  /* The instruction itself.  */
  rtx_insn *insn;

  /* If this instruction is in model_worklist, these fields link to the
     previous (higher-priority) and next (lower-priority) instructions
     in the list.  */
  struct model_insn_info *prev;
  struct model_insn_info *next;

  /* While constructing the schedule, QUEUE_INDEX describes whether an
     instruction has already been added to the schedule (QUEUE_SCHEDULED),
     is in model_worklist (QUEUE_READY), or neither (QUEUE_NOWHERE).
     old_queue records the value that QUEUE_INDEX had before scheduling
     started, so that we can restore it once the schedule is complete.  */
  int old_queue;

  /* The relative importance of an unscheduled instruction.  Higher
     values indicate greater importance.  */
  unsigned int model_priority;

  /* The length of the longest path of satisfied true dependencies
     that leads to this instruction.  */
  unsigned int depth;

  /* The length of the longest path of dependencies of any kind
     that leads from this instruction.  */
  unsigned int alap;

  /* The number of predecessor nodes that must still be scheduled.  */
  int unscheduled_preds;
};

/* Information about the pressure limit for a particular register class.
   This structure is used when applying a model schedule to the main
   schedule.  */
struct model_pressure_limit {
  /* The maximum register pressure seen in the original model schedule.  */
  int orig_pressure;

  /* The maximum register pressure seen in the current model schedule
     (which excludes instructions that have already been scheduled).  */
  int pressure;

  /* The point of the current model schedule at which PRESSURE is first
     reached.  It is set to -1 if the value needs to be recomputed.  */
  int point;
};

/* Describes a particular way of measuring register pressure.  */
struct model_pressure_group {
  /* Index PCI describes the maximum pressure on ira_pressure_classes[PCI].  */
  struct model_pressure_limit limits[N_REG_CLASSES];

  /* Index (POINT * ira_num_pressure_classes + PCI) describes the pressure
     on register class ira_pressure_classes[PCI] at point POINT of the
     current model schedule.  A POINT of model_num_insns describes the
     pressure at the end of the schedule.  */
  struct model_pressure_data *model;
};

/* Index POINT gives the instruction at point POINT of the model schedule.
   This array doesn't change during main scheduling.  */
static vec<rtx_insn *> model_schedule;

/* The list of instructions in the model worklist, sorted in order of
   decreasing priority.  */
static struct model_insn_info *model_worklist;

/* Index I describes the instruction with INSN_LUID I.  */
static struct model_insn_info *model_insns;

/* The number of instructions in the model schedule.  */
static int model_num_insns;

/* The index of the first instruction in model_schedule that hasn't yet been
   added to the main schedule, or model_num_insns if all of them have.  */
static int model_curr_point;

/* Describes the pressure before each instruction in the model schedule.  */
static struct model_pressure_group model_before_pressure;

/* The first unused model_priority value (as used in model_insn_info).  */
static unsigned int model_next_priority;


/* The model_pressure_data for ira_pressure_classes[PCI] in GROUP
   at point POINT of the model schedule.  */
#define MODEL_PRESSURE_DATA(GROUP, POINT, PCI) \
  (&(GROUP)->model[(POINT) * ira_pressure_classes_num + (PCI)])

/* The maximum pressure on ira_pressure_classes[PCI] in GROUP at or
   after point POINT of the model schedule.  */
#define MODEL_MAX_PRESSURE(GROUP, POINT, PCI) \
  (MODEL_PRESSURE_DATA (GROUP, POINT, PCI)->max_pressure)

/* The pressure on ira_pressure_classes[PCI] in GROUP at point POINT
   of the model schedule.  */
#define MODEL_REF_PRESSURE(GROUP, POINT, PCI) \
  (MODEL_PRESSURE_DATA (GROUP, POINT, PCI)->ref_pressure)

/* Information about INSN that is used when creating the model schedule.  */
#define MODEL_INSN_INFO(INSN) \
  (&model_insns[INSN_LUID (INSN)])

/* The instruction at point POINT of the model schedule.  */
#define MODEL_INSN(POINT) \
  (model_schedule[POINT])


/* Return INSN's index in the model schedule, or model_num_insns if it
   doesn't belong to that schedule.  */

static int
model_index (rtx_insn *insn)
{
  if (INSN_MODEL_INDEX (insn) == 0)
    return model_num_insns;
  return INSN_MODEL_INDEX (insn) - 1;
}

/* Make sure that GROUP->limits is up-to-date for the current point
   of the model schedule.  */

static void
model_update_limit_points_in_group (struct model_pressure_group *group)
{
  int pci, max_pressure, point;

  for (pci = 0; pci < ira_pressure_classes_num; pci++)
    {
      /* We may have passed the final point at which the pressure in
	 group->limits[pci].pressure was reached.  Update the limit if so.  */
      max_pressure = MODEL_MAX_PRESSURE (group, model_curr_point, pci);
      group->limits[pci].pressure = max_pressure;

      /* Find the point at which MAX_PRESSURE is first reached.  We need
	 to search in three cases:

	 - We've already moved past the previous pressure point.
	   In this case we search forward from model_curr_point.

	 - We scheduled the previous point of maximum pressure ahead of
	   its position in the model schedule, but doing so didn't bring
	   the pressure point earlier.  In this case we search forward
	   from that previous pressure point.

	 - Scheduling an instruction early caused the maximum pressure
	   to decrease.  In this case we will have set the pressure
	   point to -1, and we search forward from model_curr_point.  */
      point = MAX (group->limits[pci].point, model_curr_point);
      while (point < model_num_insns
	     && MODEL_REF_PRESSURE (group, point, pci) < max_pressure)
	point++;
      group->limits[pci].point = point;

      gcc_assert (MODEL_REF_PRESSURE (group, point, pci) == max_pressure);
      gcc_assert (MODEL_MAX_PRESSURE (group, point, pci) == max_pressure);
    }
}

/* Make sure that all register-pressure limits are up-to-date for the
   current position in the model schedule.  */

static void
model_update_limit_points (void)
{
  model_update_limit_points_in_group (&model_before_pressure);
}

/* Return the model_index of the last unscheduled use in chain USE
   outside of USE's instruction.  Return -1 if there are no other uses,
   or model_num_insns if the register is live at the end of the block.  */

static int
model_last_use_except (struct reg_use_data *use)
{
  struct reg_use_data *next;
  int last, index;

  last = -1;
  for (next = use->next_regno_use; next != use; next = next->next_regno_use)
    if (NONDEBUG_INSN_P (next->insn)
	&& QUEUE_INDEX (next->insn) != QUEUE_SCHEDULED)
      {
	index = model_index (next->insn);
	if (index == model_num_insns)
	  return model_num_insns;
	if (last < index)
	  last = index;
      }
  return last;
}

/* An instruction with model_index POINT has just been scheduled, and it
   adds DELTA to the pressure on ira_pressure_classes[PCI] after POINT - 1.
   Update MODEL_REF_PRESSURE (GROUP, POINT, PCI) and
   MODEL_MAX_PRESSURE (GROUP, POINT, PCI) accordingly.  */

static void
model_start_update_pressure (struct model_pressure_group *group,
			     int point, int pci, int delta)
{
  int next_max_pressure;

  if (point == model_num_insns)
    {
      /* The instruction wasn't part of the model schedule; it was moved
	 from a different block.  Update the pressure for the end of
	 the model schedule.  */
      MODEL_REF_PRESSURE (group, point, pci) += delta;
      MODEL_MAX_PRESSURE (group, point, pci) += delta;
    }
  else
    {
      /* Record that this instruction has been scheduled.  Nothing now
	 changes between POINT and POINT + 1, so get the maximum pressure
	 from the latter.  If the maximum pressure decreases, the new
	 pressure point may be before POINT.  */
      MODEL_REF_PRESSURE (group, point, pci) = -1;
      next_max_pressure = MODEL_MAX_PRESSURE (group, point + 1, pci);
      if (MODEL_MAX_PRESSURE (group, point, pci) > next_max_pressure)
	{
	  MODEL_MAX_PRESSURE (group, point, pci) = next_max_pressure;
	  if (group->limits[pci].point == point)
	    group->limits[pci].point = -1;
	}
    }
}

/* Record that scheduling a later instruction has changed the pressure
   at point POINT of the model schedule by DELTA (which might be 0).
   Update GROUP accordingly.  Return nonzero if these changes might
   trigger changes to previous points as well.  */

static int
model_update_pressure (struct model_pressure_group *group,
		       int point, int pci, int delta)
{
  int ref_pressure, max_pressure, next_max_pressure;

  /* If POINT hasn't yet been scheduled, update its pressure.  */
  ref_pressure = MODEL_REF_PRESSURE (group, point, pci);
  if (ref_pressure >= 0 && delta != 0)
    {
      ref_pressure += delta;
      MODEL_REF_PRESSURE (group, point, pci) = ref_pressure;

      /* Check whether the maximum pressure in the overall schedule
	 has increased.  (This means that the MODEL_MAX_PRESSURE of
	 every point <= POINT will need to increase too; see below.)  */
      if (group->limits[pci].pressure < ref_pressure)
	group->limits[pci].pressure = ref_pressure;

      /* If we are at maximum pressure, and the maximum pressure
	 point was previously unknown or later than POINT,
	 bring it forward.  */
      if (group->limits[pci].pressure == ref_pressure
	  && !IN_RANGE (group->limits[pci].point, 0, point))
	group->limits[pci].point = point;

      /* If POINT used to be the point of maximum pressure, but isn't
	 any longer, we need to recalculate it using a forward walk.  */
      if (group->limits[pci].pressure > ref_pressure
	  && group->limits[pci].point == point)
	group->limits[pci].point = -1;
    }

  /* Update the maximum pressure at POINT.  Changes here might also
     affect the maximum pressure at POINT - 1.  */
  next_max_pressure = MODEL_MAX_PRESSURE (group, point + 1, pci);
  max_pressure = MAX (ref_pressure, next_max_pressure);
  if (MODEL_MAX_PRESSURE (group, point, pci) != max_pressure)
    {
      MODEL_MAX_PRESSURE (group, point, pci) = max_pressure;
      return 1;
    }
  return 0;
}

/* INSN has just been scheduled.  Update the model schedule accordingly.  */

static void
model_recompute (rtx_insn *insn)
{
  struct {
    int last_use;
    int regno;
  } uses[FIRST_PSEUDO_REGISTER + MAX_RECOG_OPERANDS];
  struct reg_use_data *use;
  struct reg_pressure_data *reg_pressure;
  int delta[N_REG_CLASSES];
  int pci, point, mix, new_last, cl, ref_pressure, queue;
  unsigned int i, num_uses, num_pending_births;
  bool print_p;

  /* The destinations of INSN were previously live from POINT onwards, but are
     now live from model_curr_point onwards.  Set up DELTA accordingly.  */
  point = model_index (insn);
  reg_pressure = INSN_REG_PRESSURE (insn);
  for (pci = 0; pci < ira_pressure_classes_num; pci++)
    {
      cl = ira_pressure_classes[pci];
      delta[cl] = reg_pressure[pci].set_increase;
    }

  /* Record which registers previously died at POINT, but which now die
     before POINT.  Adjust DELTA so that it represents the effect of
     this change after POINT - 1.  Set NUM_PENDING_BIRTHS to the number of
     registers that will be born in the range [model_curr_point, POINT).  */
  num_uses = 0;
  num_pending_births = 0;
  bitmap_clear (tmp_bitmap);
  for (use = INSN_REG_USE_LIST (insn); use != NULL; use = use->next_insn_use)
    {
      new_last = model_last_use_except (use);
      if (new_last < point && bitmap_set_bit (tmp_bitmap, use->regno))
	{
	  gcc_assert (num_uses < ARRAY_SIZE (uses));
	  uses[num_uses].last_use = new_last;
	  uses[num_uses].regno = use->regno;
	  /* This register is no longer live after POINT - 1.  */
	  mark_regno_birth_or_death (NULL, delta, use->regno, false);
	  num_uses++;
	  if (new_last >= 0)
	    num_pending_births++;
	}
    }

  /* Update the MODEL_REF_PRESSURE and MODEL_MAX_PRESSURE for POINT.
     Also set each group pressure limit for POINT.  */
  for (pci = 0; pci < ira_pressure_classes_num; pci++)
    {
      cl = ira_pressure_classes[pci];
      model_start_update_pressure (&model_before_pressure,
				   point, pci, delta[cl]);
    }

  /* Walk the model schedule backwards, starting immediately before POINT.  */
  print_p = false;
  if (point != model_curr_point)
    do
      {
	point--;
	insn = MODEL_INSN (point);
	queue = QUEUE_INDEX (insn);

	if (queue != QUEUE_SCHEDULED)
	  {
	    /* DELTA describes the effect of the move on the register pressure
	       after POINT.  Make it describe the effect on the pressure
	       before POINT.  */
	    i = 0;
	    while (i < num_uses)
	      {
		if (uses[i].last_use == point)
		  {
		    /* This register is now live again.  */
		    mark_regno_birth_or_death (NULL, delta,
					       uses[i].regno, true);

		    /* Remove this use from the array.  */
		    uses[i] = uses[num_uses - 1];
		    num_uses--;
		    num_pending_births--;
		  }
		else
		  i++;
	      }

	    if (sched_verbose >= 5)
	      {
		if (!print_p)
		  {
		    fprintf (sched_dump, MODEL_BAR);
		    fprintf (sched_dump, ";;\t\t| New pressure for model"
			     " schedule\n");
		    fprintf (sched_dump, MODEL_BAR);
		    print_p = true;
		  }

		fprintf (sched_dump, ";;\t\t| %3d %4d %-30s ",
			 point, INSN_UID (insn),
			 str_pattern_slim (PATTERN (insn)));
		for (pci = 0; pci < ira_pressure_classes_num; pci++)
		  {
		    cl = ira_pressure_classes[pci];
		    ref_pressure = MODEL_REF_PRESSURE (&model_before_pressure,
						       point, pci);
		    fprintf (sched_dump, " %s:[%d->%d]",
			     reg_class_names[ira_pressure_classes[pci]],
			     ref_pressure, ref_pressure + delta[cl]);
		  }
		fprintf (sched_dump, "\n");
	      }
	  }

	/* Adjust the pressure at POINT.  Set MIX to nonzero if POINT - 1
	   might have changed as well.  */
	mix = num_pending_births;
	for (pci = 0; pci < ira_pressure_classes_num; pci++)
	  {
	    cl = ira_pressure_classes[pci];
	    mix |= delta[cl];
	    mix |= model_update_pressure (&model_before_pressure,
					  point, pci, delta[cl]);
	  }
      }
    while (mix && point > model_curr_point);

  if (print_p)
    fprintf (sched_dump, MODEL_BAR);
}

/* After DEP, which was cancelled, has been resolved for insn NEXT,
   check whether the insn's pattern needs restoring.  */
static bool
must_restore_pattern_p (rtx_insn *next, dep_t dep)
{
  if (QUEUE_INDEX (next) == QUEUE_SCHEDULED)
    return false;

  if (DEP_TYPE (dep) == REG_DEP_CONTROL)
    {
      gcc_assert (ORIG_PAT (next) != NULL_RTX);
      gcc_assert (next == DEP_CON (dep));
    }
  else
    {
      struct dep_replacement *desc = DEP_REPLACE (dep);
      if (desc->insn != next)
	{
	  gcc_assert (*desc->loc == desc->orig);
	  return false;
	}
    }
  return true;
}

/* model_spill_cost (CL, P, P') returns the cost of increasing the
   pressure on CL from P to P'.  We use this to calculate a "base ECC",
   baseECC (CL, X), for each pressure class CL and each instruction X.
   Supposing X changes the pressure on CL from P to P', and that the
   maximum pressure on CL in the current model schedule is MP', then:

   * if X occurs before or at the next point of maximum pressure in
     the model schedule and P' > MP', then:

       baseECC (CL, X) = model_spill_cost (CL, MP, P')

     The idea is that the pressure after scheduling a fixed set of
     instructions -- in this case, the set up to and including the
     next maximum pressure point -- is going to be the same regardless
     of the order; we simply want to keep the intermediate pressure
     under control.  Thus X has a cost of zero unless scheduling it
     now would exceed MP'.

     If all increases in the set are by the same amount, no zero-cost
     instruction will ever cause the pressure to exceed MP'.  However,
     if X is instead moved past an instruction X' with pressure in the
     range (MP' - (P' - P), MP'), the pressure at X' will increase
     beyond MP'.  Since baseECC is very much a heuristic anyway,
     it doesn't seem worth the overhead of tracking cases like these.

     The cost of exceeding MP' is always based on the original maximum
     pressure MP.  This is so that going 2 registers over the original
     limit has the same cost regardless of whether it comes from two
     separate +1 deltas or from a single +2 delta.

   * if X occurs after the next point of maximum pressure in the model
     schedule and P' > P, then:

       baseECC (CL, X) = model_spill_cost (CL, MP, MP' + (P' - P))

     That is, if we move X forward across a point of maximum pressure,
     and if X increases the pressure by P' - P, then we conservatively
     assume that scheduling X next would increase the maximum pressure
     by P' - P.  Again, the cost of doing this is based on the original
     maximum pressure MP, for the same reason as above.

   * if P' < P, P > MP, and X occurs at or after the next point of
     maximum pressure, then:

       baseECC (CL, X) = -model_spill_cost (CL, MAX (MP, P'), P)

     That is, if we have already exceeded the original maximum pressure MP,
     and if X might reduce the maximum pressure again -- or at least push
     it further back, and thus allow more scheduling freedom -- it is given
     a negative cost to reflect the improvement.

   * otherwise,

       baseECC (CL, X) = 0

     In this case, X is not expected to affect the maximum pressure MP',
     so it has zero cost.

   We then create a combined value baseECC (X) that is the sum of
   baseECC (CL, X) for each pressure class CL.

   baseECC (X) could itself be used as the ECC value described above.
   However, this is often too conservative, in the sense that it
   tends to make high-priority instructions that increase pressure
   wait too long in cases where introducing a spill would be better.
   For this reason the final ECC is a priority-adjusted form of
   baseECC (X).  Specifically, we calculate:

     P (X) = INSN_PRIORITY (X) - insn_delay (X) - baseECC (X)
     baseP = MAX { P (X) | baseECC (X) <= 0 }

   Then:

     ECC (X) = MAX (MIN (baseP - P (X), baseECC (X)), 0)

   Thus an instruction's effect on pressure is ignored if it has a high
   enough priority relative to the ones that don't increase pressure.
   Negative values of baseECC (X) do not increase the priority of X
   itself, but they do make it harder for other instructions to
   increase the pressure further.

   This pressure cost is deliberately timid.  The intention has been
   to choose a heuristic that rarely interferes with the normal list
   scheduler in cases where that scheduler would produce good code.
   We simply want to curb some of its worst excesses.  */

/* Return the cost of increasing the pressure in class CL from FROM to TO.

   Here we use the very simplistic cost model that every register above
   sched_class_regs_num[CL] has a spill cost of 1.  We could use other
   measures instead, such as one based on MEMORY_MOVE_COST.  However:

      (1) In order for an instruction to be scheduled, the higher cost
	  would need to be justified in a single saving of that many stalls.
	  This is overly pessimistic, because the benefit of spilling is
	  often to avoid a sequence of several short stalls rather than
	  a single long one.

      (2) The cost is still arbitrary.  Because we are not allocating
	  registers during scheduling, we have no way of knowing for
	  sure how many memory accesses will be required by each spill,
	  where the spills will be placed within the block, or even
	  which block(s) will contain the spills.

   So a higher cost than 1 is often too conservative in practice,
   forcing blocks to contain unnecessary stalls instead of spill code.
   The simple cost below seems to be the best compromise.  It reduces
   the interference with the normal list scheduler, which helps make
   it more suitable for a default-on option.  */

static int
model_spill_cost (int cl, int from, int to)
{
  from = MAX (from, sched_class_regs_num[cl]);
  return MAX (to, from) - from;
}

/* Return baseECC (ira_pressure_classes[PCI], POINT), given that
   P = curr_reg_pressure[ira_pressure_classes[PCI]] and that
   P' = P + DELTA.  */

static int
model_excess_group_cost (struct model_pressure_group *group,
			 int point, int pci, int delta)
{
  int pressure, cl;

  cl = ira_pressure_classes[pci];
  if (delta < 0 && point >= group->limits[pci].point)
    {
      pressure = MAX (group->limits[pci].orig_pressure,
		      curr_reg_pressure[cl] + delta);
      return -model_spill_cost (cl, pressure, curr_reg_pressure[cl]);
    }

  if (delta > 0)
    {
      if (point > group->limits[pci].point)
	pressure = group->limits[pci].pressure + delta;
      else
	pressure = curr_reg_pressure[cl] + delta;

      if (pressure > group->limits[pci].pressure)
	return model_spill_cost (cl, group->limits[pci].orig_pressure,
				 pressure);
    }

  return 0;
}

/* Return baseECC (MODEL_INSN (INSN)).  Dump the costs to sched_dump
   if PRINT_P.  */

static int
model_excess_cost (rtx_insn *insn, bool print_p)
{
  int point, pci, cl, cost, this_cost, delta;
  struct reg_pressure_data *insn_reg_pressure;
  int insn_death[N_REG_CLASSES];

  calculate_reg_deaths (insn, insn_death);
  point = model_index (insn);
  insn_reg_pressure = INSN_REG_PRESSURE (insn);
  cost = 0;

  if (print_p)
    fprintf (sched_dump, ";;\t\t| %3d %4d | %4d %+3d |", point,
	     INSN_UID (insn), INSN_PRIORITY (insn), insn_delay (insn));

  /* Sum up the individual costs for each register class.  */
  for (pci = 0; pci < ira_pressure_classes_num; pci++)
    {
      cl = ira_pressure_classes[pci];
      delta = insn_reg_pressure[pci].set_increase - insn_death[cl];
      this_cost = model_excess_group_cost (&model_before_pressure,
					   point, pci, delta);
      cost += this_cost;
      if (print_p)
	fprintf (sched_dump, " %s:[%d base cost %d]",
		 reg_class_names[cl], delta, this_cost);
    }

  if (print_p)
    fprintf (sched_dump, "\n");

  return cost;
}

/* Dump the next points of maximum pressure for GROUP.  */

static void
model_dump_pressure_points (struct model_pressure_group *group)
{
  int pci, cl;

  fprintf (sched_dump, ";;\t\t|  pressure points");
  for (pci = 0; pci < ira_pressure_classes_num; pci++)
    {
      cl = ira_pressure_classes[pci];
      fprintf (sched_dump, " %s:[%d->%d at ", reg_class_names[cl],
	       curr_reg_pressure[cl], group->limits[pci].pressure);
      if (group->limits[pci].point < model_num_insns)
	fprintf (sched_dump, "%d:%d]", group->limits[pci].point,
		 INSN_UID (MODEL_INSN (group->limits[pci].point)));
      else
	fprintf (sched_dump, "end]");
    }
  fprintf (sched_dump, "\n");
}

/* Set INSN_REG_PRESSURE_EXCESS_COST_CHANGE for INSNS[0...COUNT-1].  */

static void
model_set_excess_costs (rtx_insn **insns, int count)
{
  int i, cost, priority_base, priority;
  bool print_p;

  /* Record the baseECC value for each instruction in the model schedule,
     except that negative costs are converted to zero ones now rather than
     later.  Do not assign a cost to debug instructions, since they must
     not change code-generation decisions.  Experiments suggest we also
     get better results by not assigning a cost to instructions from
     a different block.

     Set PRIORITY_BASE to baseP in the block comment above.  This is the
     maximum priority of the "cheap" instructions, which should always
     include the next model instruction.  */
  priority_base = 0;
  print_p = false;
  for (i = 0; i < count; i++)
    if (INSN_MODEL_INDEX (insns[i]))
      {
	if (sched_verbose >= 6 && !print_p)
	  {
	    fprintf (sched_dump, MODEL_BAR);
	    fprintf (sched_dump, ";;\t\t| Pressure costs for ready queue\n");
	    model_dump_pressure_points (&model_before_pressure);
	    fprintf (sched_dump, MODEL_BAR);
	    print_p = true;
	  }
	cost = model_excess_cost (insns[i], print_p);
	if (cost <= 0)
	  {
	    priority = INSN_PRIORITY (insns[i]) - insn_delay (insns[i]) - cost;
	    priority_base = MAX (priority_base, priority);
	    cost = 0;
	  }
	INSN_REG_PRESSURE_EXCESS_COST_CHANGE (insns[i]) = cost;
      }
  if (print_p)
    fprintf (sched_dump, MODEL_BAR);

  /* Use MAX (baseECC, 0) and baseP to calculcate ECC for each
     instruction.  */
  for (i = 0; i < count; i++)
    {
      cost = INSN_REG_PRESSURE_EXCESS_COST_CHANGE (insns[i]);
      priority = INSN_PRIORITY (insns[i]) - insn_delay (insns[i]);
      if (cost > 0 && priority > priority_base)
	{
	  cost += priority_base - priority;
	  INSN_REG_PRESSURE_EXCESS_COST_CHANGE (insns[i]) = MAX (cost, 0);
	}
    }
}


/* Enum of rank_for_schedule heuristic decisions.  */
enum rfs_decision {
  RFS_LIVE_RANGE_SHRINK1, RFS_LIVE_RANGE_SHRINK2,
  RFS_SCHED_GROUP, RFS_PRESSURE_DELAY, RFS_PRESSURE_TICK,
  RFS_FEEDS_BACKTRACK_INSN, RFS_PRIORITY, RFS_SPECULATION,
  RFS_SCHED_RANK, RFS_LAST_INSN, RFS_PRESSURE_INDEX,
  RFS_DEP_COUNT, RFS_TIE, RFS_FUSION, RFS_COST, RFS_N };

/* Corresponding strings for print outs.  */
static const char *rfs_str[RFS_N] = {
  "RFS_LIVE_RANGE_SHRINK1", "RFS_LIVE_RANGE_SHRINK2",
  "RFS_SCHED_GROUP", "RFS_PRESSURE_DELAY", "RFS_PRESSURE_TICK",
  "RFS_FEEDS_BACKTRACK_INSN", "RFS_PRIORITY", "RFS_SPECULATION",
  "RFS_SCHED_RANK", "RFS_LAST_INSN", "RFS_PRESSURE_INDEX",
  "RFS_DEP_COUNT", "RFS_TIE", "RFS_FUSION", "RFS_COST" };

/* Statistical breakdown of rank_for_schedule decisions.  */
struct rank_for_schedule_stats_t { unsigned stats[RFS_N]; };
static rank_for_schedule_stats_t rank_for_schedule_stats;

/* Return the result of comparing insns TMP and TMP2 and update
   Rank_For_Schedule statistics.  */
static int
rfs_result (enum rfs_decision decision, int result, rtx tmp, rtx tmp2)
{
  ++rank_for_schedule_stats.stats[decision];
  if (result < 0)
    INSN_LAST_RFS_WIN (tmp) = decision;
  else if (result > 0)
    INSN_LAST_RFS_WIN (tmp2) = decision;
  else
    gcc_unreachable ();
  return result;
}

/* Sorting predicate to move DEBUG_INSNs to the top of ready list, while
   keeping normal insns in original order.  */

static int
rank_for_schedule_debug (const void *x, const void *y)
{
  rtx_insn *tmp = *(rtx_insn * const *) y;
  rtx_insn *tmp2 = *(rtx_insn * const *) x;

  /* Schedule debug insns as early as possible.  */
  if (DEBUG_INSN_P (tmp) && !DEBUG_INSN_P (tmp2))
    return -1;
  else if (!DEBUG_INSN_P (tmp) && DEBUG_INSN_P (tmp2))
    return 1;
  else if (DEBUG_INSN_P (tmp) && DEBUG_INSN_P (tmp2))
    return INSN_LUID (tmp) - INSN_LUID (tmp2);
  else
    return INSN_RFS_DEBUG_ORIG_ORDER (tmp2) - INSN_RFS_DEBUG_ORIG_ORDER (tmp);
}

/* Returns a positive value if x is preferred; returns a negative value if
   y is preferred.  Should never return 0, since that will make the sort
   unstable.  */

static int
rank_for_schedule (const void *x, const void *y)
{
  rtx_insn *tmp = *(rtx_insn * const *) y;
  rtx_insn *tmp2 = *(rtx_insn * const *) x;
  int tmp_class, tmp2_class;
  int val, priority_val, info_val, diff;

  if (live_range_shrinkage_p)
    {
      /* Don't use SCHED_PRESSURE_MODEL -- it results in much worse
	 code.  */
      gcc_assert (sched_pressure == SCHED_PRESSURE_WEIGHTED);
      if ((INSN_REG_PRESSURE_EXCESS_COST_CHANGE (tmp) < 0
	   || INSN_REG_PRESSURE_EXCESS_COST_CHANGE (tmp2) < 0)
	  && (diff = (INSN_REG_PRESSURE_EXCESS_COST_CHANGE (tmp)
		      - INSN_REG_PRESSURE_EXCESS_COST_CHANGE (tmp2))) != 0)
	return rfs_result (RFS_LIVE_RANGE_SHRINK1, diff, tmp, tmp2);
      /* Sort by INSN_LUID (original insn order), so that we make the
	 sort stable.  This minimizes instruction movement, thus
	 minimizing sched's effect on debugging and cross-jumping.  */
      return rfs_result (RFS_LIVE_RANGE_SHRINK2,
			 INSN_LUID (tmp) - INSN_LUID (tmp2), tmp, tmp2);
    }

  /* The insn in a schedule group should be issued the first.  */
  if (flag_sched_group_heuristic &&
      SCHED_GROUP_P (tmp) != SCHED_GROUP_P (tmp2))
    return rfs_result (RFS_SCHED_GROUP, SCHED_GROUP_P (tmp2) ? 1 : -1,
		       tmp, tmp2);

  /* Make sure that priority of TMP and TMP2 are initialized.  */
  gcc_assert (INSN_PRIORITY_KNOWN (tmp) && INSN_PRIORITY_KNOWN (tmp2));

  if (sched_fusion)
    {
      /* The instruction that has the same fusion priority as the last
	 instruction is the instruction we picked next.  If that is not
	 the case, we sort ready list firstly by fusion priority, then
	 by priority, and at last by INSN_LUID.  */
      int a = INSN_FUSION_PRIORITY (tmp);
      int b = INSN_FUSION_PRIORITY (tmp2);
      int last = -1;

      if (last_nondebug_scheduled_insn
	  && !NOTE_P (last_nondebug_scheduled_insn)
	  && BLOCK_FOR_INSN (tmp)
	       == BLOCK_FOR_INSN (last_nondebug_scheduled_insn))
	last = INSN_FUSION_PRIORITY (last_nondebug_scheduled_insn);

      if (a != last && b != last)
	{
	  if (a == b)
	    {
	      a = INSN_PRIORITY (tmp);
	      b = INSN_PRIORITY (tmp2);
	    }
	  if (a != b)
	    return rfs_result (RFS_FUSION, b - a, tmp, tmp2);
	  else
	    return rfs_result (RFS_FUSION,
			       INSN_LUID (tmp) - INSN_LUID (tmp2), tmp, tmp2);
	}
      else if (a == b)
	{
	  gcc_assert (last_nondebug_scheduled_insn
		      && !NOTE_P (last_nondebug_scheduled_insn));
	  last = INSN_PRIORITY (last_nondebug_scheduled_insn);

	  a = abs (INSN_PRIORITY (tmp) - last);
	  b = abs (INSN_PRIORITY (tmp2) - last);
	  if (a != b)
	    return rfs_result (RFS_FUSION, a - b, tmp, tmp2);
	  else
	    return rfs_result (RFS_FUSION,
			       INSN_LUID (tmp) - INSN_LUID (tmp2), tmp, tmp2);
	}
      else if (a == last)
	return rfs_result (RFS_FUSION, -1, tmp, tmp2);
      else
	return rfs_result (RFS_FUSION, 1, tmp, tmp2);
    }

  if (sched_pressure != SCHED_PRESSURE_NONE)
    {
      /* Prefer insn whose scheduling results in the smallest register
	 pressure excess.  */
      if ((diff = (INSN_REG_PRESSURE_EXCESS_COST_CHANGE (tmp)
		   + insn_delay (tmp)
		   - INSN_REG_PRESSURE_EXCESS_COST_CHANGE (tmp2)
		   - insn_delay (tmp2))))
	return rfs_result (RFS_PRESSURE_DELAY, diff, tmp, tmp2);
    }

  if (sched_pressure != SCHED_PRESSURE_NONE
      && (INSN_TICK (tmp2) > clock_var || INSN_TICK (tmp) > clock_var)
      && INSN_TICK (tmp2) != INSN_TICK (tmp))
    {
      diff = INSN_TICK (tmp) - INSN_TICK (tmp2);
      return rfs_result (RFS_PRESSURE_TICK, diff, tmp, tmp2);
    }

  /* If we are doing backtracking in this schedule, prefer insns that
     have forward dependencies with negative cost against an insn that
     was already scheduled.  */
  if (current_sched_info->flags & DO_BACKTRACKING)
    {
      priority_val = FEEDS_BACKTRACK_INSN (tmp2) - FEEDS_BACKTRACK_INSN (tmp);
      if (priority_val)
	return rfs_result (RFS_FEEDS_BACKTRACK_INSN, priority_val, tmp, tmp2);
    }

  /* Prefer insn with higher priority.  */
  priority_val = INSN_PRIORITY (tmp2) - INSN_PRIORITY (tmp);

  if (flag_sched_critical_path_heuristic && priority_val)
    return rfs_result (RFS_PRIORITY, priority_val, tmp, tmp2);

  if (param_sched_autopref_queue_depth >= 0)
    {
      int autopref = autopref_rank_for_schedule (tmp, tmp2);
      if (autopref != 0)
	return autopref;
    }

  /* Prefer speculative insn with greater dependencies weakness.  */
  if (flag_sched_spec_insn_heuristic && spec_info)
    {
      ds_t ds1, ds2;
      dw_t dw1, dw2;
      int dw;

      ds1 = TODO_SPEC (tmp) & SPECULATIVE;
      if (ds1)
	dw1 = ds_weak (ds1);
      else
	dw1 = NO_DEP_WEAK;

      ds2 = TODO_SPEC (tmp2) & SPECULATIVE;
      if (ds2)
	dw2 = ds_weak (ds2);
      else
	dw2 = NO_DEP_WEAK;

      dw = dw2 - dw1;
      if (dw > (NO_DEP_WEAK / 8) || dw < -(NO_DEP_WEAK / 8))
	return rfs_result (RFS_SPECULATION, dw, tmp, tmp2);
    }

  info_val = (*current_sched_info->rank) (tmp, tmp2);
  if (flag_sched_rank_heuristic && info_val)
    return rfs_result (RFS_SCHED_RANK, info_val, tmp, tmp2);

  /* Compare insns based on their relation to the last scheduled
     non-debug insn.  */
  if (flag_sched_last_insn_heuristic && last_nondebug_scheduled_insn)
    {
      dep_t dep1;
      dep_t dep2;
      rtx_insn *last = last_nondebug_scheduled_insn;

      /* Classify the instructions into three classes:
         1) Data dependent on last schedule insn.
         2) Anti/Output dependent on last scheduled insn.
         3) Independent of last scheduled insn, or has latency of one.
         Choose the insn from the highest numbered class if different.  */
      dep1 = sd_find_dep_between (last, tmp, true);

      if (dep1 == NULL || dep_cost (dep1) == 1)
	tmp_class = 3;
      else if (/* Data dependence.  */
	       DEP_TYPE (dep1) == REG_DEP_TRUE)
	tmp_class = 1;
      else
	tmp_class = 2;

      dep2 = sd_find_dep_between (last, tmp2, true);

      if (dep2 == NULL || dep_cost (dep2)  == 1)
	tmp2_class = 3;
      else if (/* Data dependence.  */
	       DEP_TYPE (dep2) == REG_DEP_TRUE)
	tmp2_class = 1;
      else
	tmp2_class = 2;

      if ((val = tmp2_class - tmp_class))
	return rfs_result (RFS_LAST_INSN, val, tmp, tmp2);
    }

  /* Prefer instructions that occur earlier in the model schedule.  */
  if (sched_pressure == SCHED_PRESSURE_MODEL)
    {
      diff = model_index (tmp) - model_index (tmp2);
      if (diff != 0)
	return rfs_result (RFS_PRESSURE_INDEX, diff, tmp, tmp2);
    }

  /* Prefer the insn which has more later insns that depend on it.
     This gives the scheduler more freedom when scheduling later
     instructions at the expense of added register pressure.  */

  val = (dep_list_size (tmp2, SD_LIST_FORW)
	 - dep_list_size (tmp, SD_LIST_FORW));

  if (flag_sched_dep_count_heuristic && val != 0)
    return rfs_result (RFS_DEP_COUNT, val, tmp, tmp2);

  /* Sort by INSN_COST rather than INSN_LUID.  This means that instructions
     which take longer to execute are prioritised and it leads to more
     dual-issue opportunities on in-order cores which have this feature.  */

  if (INSN_COST (tmp) != INSN_COST (tmp2))
    return rfs_result (RFS_COST, INSN_COST (tmp2) - INSN_COST (tmp),
		       tmp, tmp2);

  /* If insns are equally good, sort by INSN_LUID (original insn order),
     so that we make the sort stable.  This minimizes instruction movement,
     thus minimizing sched's effect on debugging and cross-jumping.  */
  return rfs_result (RFS_TIE, INSN_LUID (tmp) - INSN_LUID (tmp2), tmp, tmp2);
}

/* Resort the array A in which only element at index N may be out of order.  */

HAIFA_INLINE static void
swap_sort (rtx_insn **a, int n)
{
  rtx_insn *insn = a[n - 1];
  int i = n - 2;

  while (i >= 0 && rank_for_schedule (a + i, &insn) >= 0)
    {
      a[i + 1] = a[i];
      i -= 1;
    }
  a[i + 1] = insn;
}

/* Add INSN to the insn queue so that it can be executed at least
   N_CYCLES after the currently executing insn.  Preserve insns
   chain for debugging purposes.  REASON will be printed in debugging
   output.  */

HAIFA_INLINE static void
queue_insn (rtx_insn *insn, int n_cycles, const char *reason)
{
  int next_q = NEXT_Q_AFTER (q_ptr, n_cycles);
  rtx_insn_list *link = alloc_INSN_LIST (insn, insn_queue[next_q]);
  int new_tick;

  gcc_assert (n_cycles <= max_insn_queue_index);
  gcc_assert (!DEBUG_INSN_P (insn));

  insn_queue[next_q] = link;
  q_size += 1;

  if (sched_verbose >= 2)
    {
      fprintf (sched_dump, ";;\t\tReady-->Q: insn %s: ",
	       (*current_sched_info->print_insn) (insn, 0));

      fprintf (sched_dump, "queued for %d cycles (%s).\n", n_cycles, reason);
    }

  QUEUE_INDEX (insn) = next_q;

  if (current_sched_info->flags & DO_BACKTRACKING)
    {
      new_tick = clock_var + n_cycles;
      if (INSN_TICK (insn) == INVALID_TICK || INSN_TICK (insn) < new_tick)
	INSN_TICK (insn) = new_tick;

      if (INSN_EXACT_TICK (insn) != INVALID_TICK
	  && INSN_EXACT_TICK (insn) < clock_var + n_cycles)
	{
	  must_backtrack = true;
	  if (sched_verbose >= 2)
	    fprintf (sched_dump, ";;\t\tcausing a backtrack.\n");
	}
    }
}

/* Remove INSN from queue.  */
static void
queue_remove (rtx_insn *insn)
{
  gcc_assert (QUEUE_INDEX (insn) >= 0);
  remove_free_INSN_LIST_elem (insn, &insn_queue[QUEUE_INDEX (insn)]);
  q_size--;
  QUEUE_INDEX (insn) = QUEUE_NOWHERE;
}

/* Return a pointer to the bottom of the ready list, i.e. the insn
   with the lowest priority.  */

rtx_insn **
ready_lastpos (struct ready_list *ready)
{
  gcc_assert (ready->n_ready >= 1);
  return ready->vec + ready->first - ready->n_ready + 1;
}

/* Add an element INSN to the ready list so that it ends up with the
   lowest/highest priority depending on FIRST_P.  */

HAIFA_INLINE static void
ready_add (struct ready_list *ready, rtx_insn *insn, bool first_p)
{
  if (!first_p)
    {
      if (ready->first == ready->n_ready)
	{
	  memmove (ready->vec + ready->veclen - ready->n_ready,
		   ready_lastpos (ready),
		   ready->n_ready * sizeof (rtx));
	  ready->first = ready->veclen - 1;
	}
      ready->vec[ready->first - ready->n_ready] = insn;
    }
  else
    {
      if (ready->first == ready->veclen - 1)
	{
	  if (ready->n_ready)
	    /* ready_lastpos() fails when called with (ready->n_ready == 0).  */
	    memmove (ready->vec + ready->veclen - ready->n_ready - 1,
		     ready_lastpos (ready),
		     ready->n_ready * sizeof (rtx));
	  ready->first = ready->veclen - 2;
	}
      ready->vec[++(ready->first)] = insn;
    }

  ready->n_ready++;
  if (DEBUG_INSN_P (insn))
    ready->n_debug++;

  gcc_assert (QUEUE_INDEX (insn) != QUEUE_READY);
  QUEUE_INDEX (insn) = QUEUE_READY;

  if (INSN_EXACT_TICK (insn) != INVALID_TICK
      && INSN_EXACT_TICK (insn) < clock_var)
    {
      must_backtrack = true;
    }
}

/* Remove the element with the highest priority from the ready list and
   return it.  */

HAIFA_INLINE static rtx_insn *
ready_remove_first (struct ready_list *ready)
{
  rtx_insn *t;

  gcc_assert (ready->n_ready);
  t = ready->vec[ready->first--];
  ready->n_ready--;
  if (DEBUG_INSN_P (t))
    ready->n_debug--;
  /* If the queue becomes empty, reset it.  */
  if (ready->n_ready == 0)
    ready->first = ready->veclen - 1;

  gcc_assert (QUEUE_INDEX (t) == QUEUE_READY);
  QUEUE_INDEX (t) = QUEUE_NOWHERE;

  return t;
}

/* The following code implements multi-pass scheduling for the first
   cycle.  In other words, we will try to choose ready insn which
   permits to start maximum number of insns on the same cycle.  */

/* Return a pointer to the element INDEX from the ready.  INDEX for
   insn with the highest priority is 0, and the lowest priority has
   N_READY - 1.  */

rtx_insn *
ready_element (struct ready_list *ready, int index)
{
  gcc_assert (ready->n_ready && index < ready->n_ready);

  return ready->vec[ready->first - index];
}

/* Remove the element INDEX from the ready list and return it.  INDEX
   for insn with the highest priority is 0, and the lowest priority
   has N_READY - 1.  */

HAIFA_INLINE static rtx_insn *
ready_remove (struct ready_list *ready, int index)
{
  rtx_insn *t;
  int i;

  if (index == 0)
    return ready_remove_first (ready);
  gcc_assert (ready->n_ready && index < ready->n_ready);
  t = ready->vec[ready->first - index];
  ready->n_ready--;
  if (DEBUG_INSN_P (t))
    ready->n_debug--;
  for (i = index; i < ready->n_ready; i++)
    ready->vec[ready->first - i] = ready->vec[ready->first - i - 1];
  QUEUE_INDEX (t) = QUEUE_NOWHERE;
  return t;
}

/* Remove INSN from the ready list.  */
static void
ready_remove_insn (rtx_insn *insn)
{
  int i;

  for (i = 0; i < readyp->n_ready; i++)
    if (ready_element (readyp, i) == insn)
      {
        ready_remove (readyp, i);
        return;
      }
  gcc_unreachable ();
}

/* Calculate difference of two statistics set WAS and NOW.
   Result returned in WAS.  */
static void
rank_for_schedule_stats_diff (rank_for_schedule_stats_t *was,
			      const rank_for_schedule_stats_t *now)
{
  for (int i = 0; i < RFS_N; ++i)
    was->stats[i] = now->stats[i] - was->stats[i];
}

/* Print rank_for_schedule statistics.  */
static void
print_rank_for_schedule_stats (const char *prefix,
			       const rank_for_schedule_stats_t *stats,
			       struct ready_list *ready)
{
  for (int i = 0; i < RFS_N; ++i)
    if (stats->stats[i])
      {
	fprintf (sched_dump, "%s%20s: %u", prefix, rfs_str[i], stats->stats[i]);

	if (ready != NULL)
	  /* Print out insns that won due to RFS_<I>.  */
	  {
	    rtx_insn **p = ready_lastpos (ready);

	    fprintf (sched_dump, ":");
	    /* Start with 1 since least-priority insn didn't have any wins.  */
	    for (int j = 1; j < ready->n_ready; ++j)
	      if (INSN_LAST_RFS_WIN (p[j]) == i)
		fprintf (sched_dump, " %s",
			 (*current_sched_info->print_insn) (p[j], 0));
	  }
	fprintf (sched_dump, "\n");
      }
}

/* Separate DEBUG_INSNS from normal insns.  DEBUG_INSNs go to the end
   of array.  */
static void
ready_sort_debug (struct ready_list *ready)
{
  int i;
  rtx_insn **first = ready_lastpos (ready);

  for (i = 0; i < ready->n_ready; ++i)
    if (!DEBUG_INSN_P (first[i]))
      INSN_RFS_DEBUG_ORIG_ORDER (first[i]) = i;

  qsort (first, ready->n_ready, sizeof (rtx), rank_for_schedule_debug);
}

/* Sort non-debug insns in the ready list READY by ascending priority.
   Assumes that all debug insns are separated from the real insns.  */
static void
ready_sort_real (struct ready_list *ready)
{
  int i;
  rtx_insn **first = ready_lastpos (ready);
  int n_ready_real = ready->n_ready - ready->n_debug;

  if (sched_pressure == SCHED_PRESSURE_WEIGHTED)
    for (i = 0; i < n_ready_real; ++i)
      setup_insn_reg_pressure_info (first[i]);
  else if (sched_pressure == SCHED_PRESSURE_MODEL
	   && model_curr_point < model_num_insns)
    model_set_excess_costs (first, n_ready_real);

  rank_for_schedule_stats_t stats1;
  if (sched_verbose >= 4)
    stats1 = rank_for_schedule_stats;

  if (n_ready_real == 2)
    swap_sort (first, n_ready_real);
  else if (n_ready_real > 2)
    qsort (first, n_ready_real, sizeof (rtx), rank_for_schedule);

  if (sched_verbose >= 4)
    {
      rank_for_schedule_stats_diff (&stats1, &rank_for_schedule_stats);
      print_rank_for_schedule_stats (";;\t\t", &stats1, ready);
    }
}

/* Sort the ready list READY by ascending priority.  */
static void
ready_sort (struct ready_list *ready)
{
  if (ready->n_debug > 0)
    ready_sort_debug (ready);
  else
    ready_sort_real (ready);
}

/* PREV is an insn that is ready to execute.  Adjust its priority if that
   will help shorten or lengthen register lifetimes as appropriate.  Also
   provide a hook for the target to tweak itself.  */

HAIFA_INLINE static void
adjust_priority (rtx_insn *prev)
{
  /* ??? There used to be code here to try and estimate how an insn
     affected register lifetimes, but it did it by looking at REG_DEAD
     notes, which we removed in schedule_region.  Nor did it try to
     take into account register pressure or anything useful like that.

     Revisit when we have a machine model to work with and not before.  */

  if (targetm.sched.adjust_priority)
    INSN_PRIORITY (prev) =
      targetm.sched.adjust_priority (prev, INSN_PRIORITY (prev));
}

/* Advance DFA state STATE on one cycle.  */
void
advance_state (state_t state)
{
  if (targetm.sched.dfa_pre_advance_cycle)
    targetm.sched.dfa_pre_advance_cycle ();

  if (targetm.sched.dfa_pre_cycle_insn)
    state_transition (state,
		      targetm.sched.dfa_pre_cycle_insn ());

  state_transition (state, NULL);

  if (targetm.sched.dfa_post_cycle_insn)
    state_transition (state,
		      targetm.sched.dfa_post_cycle_insn ());

  if (targetm.sched.dfa_post_advance_cycle)
    targetm.sched.dfa_post_advance_cycle ();
}

/* Advance time on one cycle.  */
HAIFA_INLINE static void
advance_one_cycle (void)
{
  advance_state (curr_state);
  if (sched_verbose >= 4)
    fprintf (sched_dump, ";;\tAdvance the current state.\n");
}

/* Update register pressure after scheduling INSN.  */
static void
update_register_pressure (rtx_insn *insn)
{
  struct reg_use_data *use;
  struct reg_set_data *set;

  gcc_checking_assert (!DEBUG_INSN_P (insn));

  for (use = INSN_REG_USE_LIST (insn); use != NULL; use = use->next_insn_use)
    if (dying_use_p (use))
      mark_regno_birth_or_death (curr_reg_live, curr_reg_pressure,
				 use->regno, false);
  for (set = INSN_REG_SET_LIST (insn); set != NULL; set = set->next_insn_set)
    mark_regno_birth_or_death (curr_reg_live, curr_reg_pressure,
			       set->regno, true);
}

/* Set up or update (if UPDATE_P) max register pressure (see its
   meaning in sched-int.h::_haifa_insn_data) for all current BB insns
   after insn AFTER.  */
static void
setup_insn_max_reg_pressure (rtx_insn *after, bool update_p)
{
  int i, p;
  bool eq_p;
  rtx_insn *insn;
  static int max_reg_pressure[N_REG_CLASSES];

  save_reg_pressure ();
  for (i = 0; i < ira_pressure_classes_num; i++)
    max_reg_pressure[ira_pressure_classes[i]]
      = curr_reg_pressure[ira_pressure_classes[i]];
  for (insn = NEXT_INSN (after);
       insn != NULL_RTX && ! BARRIER_P (insn)
	 && BLOCK_FOR_INSN (insn) == BLOCK_FOR_INSN (after);
       insn = NEXT_INSN (insn))
    if (NONDEBUG_INSN_P (insn))
      {
	eq_p = true;
	for (i = 0; i < ira_pressure_classes_num; i++)
	  {
	    p = max_reg_pressure[ira_pressure_classes[i]];
	    if (INSN_MAX_REG_PRESSURE (insn)[i] != p)
	      {
		eq_p = false;
		INSN_MAX_REG_PRESSURE (insn)[i]
		  = max_reg_pressure[ira_pressure_classes[i]];
	      }
	  }
	if (update_p && eq_p)
	  break;
	update_register_pressure (insn);
	for (i = 0; i < ira_pressure_classes_num; i++)
	  if (max_reg_pressure[ira_pressure_classes[i]]
	      < curr_reg_pressure[ira_pressure_classes[i]])
	    max_reg_pressure[ira_pressure_classes[i]]
	      = curr_reg_pressure[ira_pressure_classes[i]];
      }
  restore_reg_pressure ();
}

/* Update the current register pressure after scheduling INSN.  Update
   also max register pressure for unscheduled insns of the current
   BB.  */
static void
update_reg_and_insn_max_reg_pressure (rtx_insn *insn)
{
  int i;
  int before[N_REG_CLASSES];

  for (i = 0; i < ira_pressure_classes_num; i++)
    before[i] = curr_reg_pressure[ira_pressure_classes[i]];
  update_register_pressure (insn);
  for (i = 0; i < ira_pressure_classes_num; i++)
    if (curr_reg_pressure[ira_pressure_classes[i]] != before[i])
      break;
  if (i < ira_pressure_classes_num)
    setup_insn_max_reg_pressure (insn, true);
}

/* Set up register pressure at the beginning of basic block BB whose
   insns starting after insn AFTER.  Set up also max register pressure
   for all insns of the basic block.  */
void
sched_setup_bb_reg_pressure_info (basic_block bb, rtx_insn *after)
{
  gcc_assert (sched_pressure == SCHED_PRESSURE_WEIGHTED);
  initiate_bb_reg_pressure_info (bb);
  setup_insn_max_reg_pressure (after, false);
}

/* If doing predication while scheduling, verify whether INSN, which
   has just been scheduled, clobbers the conditions of any
   instructions that must be predicated in order to break their
   dependencies.  If so, remove them from the queues so that they will
   only be scheduled once their control dependency is resolved.  */

static void
check_clobbered_conditions (rtx_insn *insn)
{
  HARD_REG_SET t;
  int i;

  if ((current_sched_info->flags & DO_PREDICATION) == 0)
    return;

  find_all_hard_reg_sets (insn, &t, true);

 restart:
  for (i = 0; i < ready.n_ready; i++)
    {
      rtx_insn *x = ready_element (&ready, i);
      if (TODO_SPEC (x) == DEP_CONTROL && cond_clobbered_p (x, t))
	{
	  ready_remove_insn (x);
	  goto restart;
	}
    }
  for (i = 0; i <= max_insn_queue_index; i++)
    {
      rtx_insn_list *link;
      int q = NEXT_Q_AFTER (q_ptr, i);

    restart_queue:
      for (link = insn_queue[q]; link; link = link->next ())
	{
	  rtx_insn *x = link->insn ();
	  if (TODO_SPEC (x) == DEP_CONTROL && cond_clobbered_p (x, t))
	    {
	      queue_remove (x);
	      goto restart_queue;
	    }
	}
    }
}

/* Return (in order):

   - positive if INSN adversely affects the pressure on one
     register class

   - negative if INSN reduces the pressure on one register class

   - 0 if INSN doesn't affect the pressure on any register class.  */

static int
model_classify_pressure (struct model_insn_info *insn)
{
  struct reg_pressure_data *reg_pressure;
  int death[N_REG_CLASSES];
  int pci, cl, sum;

  calculate_reg_deaths (insn->insn, death);
  reg_pressure = INSN_REG_PRESSURE (insn->insn);
  sum = 0;
  for (pci = 0; pci < ira_pressure_classes_num; pci++)
    {
      cl = ira_pressure_classes[pci];
      if (death[cl] < reg_pressure[pci].set_increase)
	return 1;
      sum += reg_pressure[pci].set_increase - death[cl];
    }
  return sum;
}

/* Return true if INSN1 should come before INSN2 in the model schedule.  */

static int
model_order_p (struct model_insn_info *insn1, struct model_insn_info *insn2)
{
  unsigned int height1, height2;
  unsigned int priority1, priority2;

  /* Prefer instructions with a higher model priority.  */
  if (insn1->model_priority != insn2->model_priority)
    return insn1->model_priority > insn2->model_priority;

  /* Combine the length of the longest path of satisfied true dependencies
     that leads to each instruction (depth) with the length of the longest
     path of any dependencies that leads from the instruction (alap).
     Prefer instructions with the greatest combined length.  If the combined
     lengths are equal, prefer instructions with the greatest depth.

     The idea is that, if we have a set S of "equal" instructions that each
     have ALAP value X, and we pick one such instruction I, any true-dependent
     successors of I that have ALAP value X - 1 should be preferred over S.
     This encourages the schedule to be "narrow" rather than "wide".
     However, if I is a low-priority instruction that we decided to
     schedule because of its model_classify_pressure, and if there
     is a set of higher-priority instructions T, the aforementioned
     successors of I should not have the edge over T.  */
  height1 = insn1->depth + insn1->alap;
  height2 = insn2->depth + insn2->alap;
  if (height1 != height2)
    return height1 > height2;
  if (insn1->depth != insn2->depth)
    return insn1->depth > insn2->depth;

  /* We have no real preference between INSN1 an INSN2 as far as attempts
     to reduce pressure go.  Prefer instructions with higher priorities.  */
  priority1 = INSN_PRIORITY (insn1->insn);
  priority2 = INSN_PRIORITY (insn2->insn);
  if (priority1 != priority2)
    return priority1 > priority2;

  /* Use the original rtl sequence as a tie-breaker.  */
  return insn1 < insn2;
}

/* Add INSN to the model worklist immediately after PREV.  Add it to the
   beginning of the list if PREV is null.  */

static void
model_add_to_worklist_at (struct model_insn_info *insn,
			  struct model_insn_info *prev)
{
  gcc_assert (QUEUE_INDEX (insn->insn) == QUEUE_NOWHERE);
  QUEUE_INDEX (insn->insn) = QUEUE_READY;

  insn->prev = prev;
  if (prev)
    {
      insn->next = prev->next;
      prev->next = insn;
    }
  else
    {
      insn->next = model_worklist;
      model_worklist = insn;
    }
  if (insn->next)
    insn->next->prev = insn;
}

/* Remove INSN from the model worklist.  */

static void
model_remove_from_worklist (struct model_insn_info *insn)
{
  gcc_assert (QUEUE_INDEX (insn->insn) == QUEUE_READY);
  QUEUE_INDEX (insn->insn) = QUEUE_NOWHERE;

  if (insn->prev)
    insn->prev->next = insn->next;
  else
    model_worklist = insn->next;
  if (insn->next)
    insn->next->prev = insn->prev;
}

/* Add INSN to the model worklist.  Start looking for a suitable position
   between neighbors PREV and NEXT, testing at most param_max_sched_ready_insns
   insns either side.  A null PREV indicates the beginning of the list and
   a null NEXT indicates the end.  */

static void
model_add_to_worklist (struct model_insn_info *insn,
		       struct model_insn_info *prev,
		       struct model_insn_info *next)
{
  int count;

  count = param_max_sched_ready_insns;
  if (count > 0 && prev && model_order_p (insn, prev))
    do
      {
	count--;
	prev = prev->prev;
      }
    while (count > 0 && prev && model_order_p (insn, prev));
  else
    while (count > 0 && next && model_order_p (next, insn))
      {
	count--;
	prev = next;
	next = next->next;
      }
  model_add_to_worklist_at (insn, prev);
}

/* INSN may now have a higher priority (in the model_order_p sense)
   than before.  Move it up the worklist if necessary.  */

static void
model_promote_insn (struct model_insn_info *insn)
{
  struct model_insn_info *prev;
  int count;

  prev = insn->prev;
  count = param_max_sched_ready_insns;
  while (count > 0 && prev && model_order_p (insn, prev))
    {
      count--;
      prev = prev->prev;
    }
  if (prev != insn->prev)
    {
      model_remove_from_worklist (insn);
      model_add_to_worklist_at (insn, prev);
    }
}

/* Add INSN to the end of the model schedule.  */

static void
model_add_to_schedule (rtx_insn *insn)
{
  unsigned int point;

  gcc_assert (QUEUE_INDEX (insn) == QUEUE_NOWHERE);
  QUEUE_INDEX (insn) = QUEUE_SCHEDULED;

  point = model_schedule.length ();
  model_schedule.quick_push (insn);
  INSN_MODEL_INDEX (insn) = point + 1;
}

/* Analyze the instructions that are to be scheduled, setting up
   MODEL_INSN_INFO (...) and model_num_insns accordingly.  Add ready
   instructions to model_worklist.  */

static void
model_analyze_insns (void)
{
  rtx_insn *start, *end, *iter;
  sd_iterator_def sd_it;
  dep_t dep;
  struct model_insn_info *insn, *con;

  model_num_insns = 0;
  start = PREV_INSN (current_sched_info->next_tail);
  end = current_sched_info->prev_head;
  for (iter = start; iter != end; iter = PREV_INSN (iter))
    if (NONDEBUG_INSN_P (iter))
      {
	insn = MODEL_INSN_INFO (iter);
	insn->insn = iter;
	FOR_EACH_DEP (iter, SD_LIST_FORW, sd_it, dep)
	  {
	    con = MODEL_INSN_INFO (DEP_CON (dep));
	    if (con->insn && insn->alap < con->alap + 1)
	      insn->alap = con->alap + 1;
	  }

	insn->old_queue = QUEUE_INDEX (iter);
	QUEUE_INDEX (iter) = QUEUE_NOWHERE;

	insn->unscheduled_preds = dep_list_size (iter, SD_LIST_HARD_BACK);
	if (insn->unscheduled_preds == 0)
	  model_add_to_worklist (insn, NULL, model_worklist);

	model_num_insns++;
      }
}

/* The global state describes the register pressure at the start of the
   model schedule.  Initialize GROUP accordingly.  */

static void
model_init_pressure_group (struct model_pressure_group *group)
{
  int pci, cl;

  for (pci = 0; pci < ira_pressure_classes_num; pci++)
    {
      cl = ira_pressure_classes[pci];
      group->limits[pci].pressure = curr_reg_pressure[cl];
      group->limits[pci].point = 0;
    }
  /* Use index model_num_insns to record the state after the last
     instruction in the model schedule.  */
  group->model = XNEWVEC (struct model_pressure_data,
			  (model_num_insns + 1) * ira_pressure_classes_num);
}

/* Record that MODEL_REF_PRESSURE (GROUP, POINT, PCI) is PRESSURE.
   Update the maximum pressure for the whole schedule.  */

static void
model_record_pressure (struct model_pressure_group *group,
		       int point, int pci, int pressure)
{
  MODEL_REF_PRESSURE (group, point, pci) = pressure;
  if (group->limits[pci].pressure < pressure)
    {
      group->limits[pci].pressure = pressure;
      group->limits[pci].point = point;
    }
}

/* INSN has just been added to the end of the model schedule.  Record its
   register-pressure information.  */

static void
model_record_pressures (struct model_insn_info *insn)
{
  struct reg_pressure_data *reg_pressure;
  int point, pci, cl, delta;
  int death[N_REG_CLASSES];

  point = model_index (insn->insn);
  if (sched_verbose >= 2)
    {
      if (point == 0)
	{
	  fprintf (sched_dump, "\n;;\tModel schedule:\n;;\n");
	  fprintf (sched_dump, ";;\t| idx insn | mpri hght dpth prio |\n");
	}
      fprintf (sched_dump, ";;\t| %3d %4d | %4d %4d %4d %4d | %-30s ",
	       point, INSN_UID (insn->insn), insn->model_priority,
	       insn->depth + insn->alap, insn->depth,
	       INSN_PRIORITY (insn->insn),
	       str_pattern_slim (PATTERN (insn->insn)));
    }
  calculate_reg_deaths (insn->insn, death);
  reg_pressure = INSN_REG_PRESSURE (insn->insn);
  for (pci = 0; pci < ira_pressure_classes_num; pci++)
    {
      cl = ira_pressure_classes[pci];
      delta = reg_pressure[pci].set_increase - death[cl];
      if (sched_verbose >= 2)
	fprintf (sched_dump, " %s:[%d,%+d]", reg_class_names[cl],
		 curr_reg_pressure[cl], delta);
      model_record_pressure (&model_before_pressure, point, pci,
			     curr_reg_pressure[cl]);
    }
  if (sched_verbose >= 2)
    fprintf (sched_dump, "\n");
}

/* All instructions have been added to the model schedule.  Record the
   final register pressure in GROUP and set up all MODEL_MAX_PRESSUREs.  */

static void
model_record_final_pressures (struct model_pressure_group *group)
{
  int point, pci, max_pressure, ref_pressure, cl;

  for (pci = 0; pci < ira_pressure_classes_num; pci++)
    {
      /* Record the final pressure for this class.  */
      cl = ira_pressure_classes[pci];
      point = model_num_insns;
      ref_pressure = curr_reg_pressure[cl];
      model_record_pressure (group, point, pci, ref_pressure);

      /* Record the original maximum pressure.  */
      group->limits[pci].orig_pressure = group->limits[pci].pressure;

      /* Update the MODEL_MAX_PRESSURE for every point of the schedule.  */
      max_pressure = ref_pressure;
      MODEL_MAX_PRESSURE (group, point, pci) = max_pressure;
      while (point > 0)
	{
	  point--;
	  ref_pressure = MODEL_REF_PRESSURE (group, point, pci);
	  max_pressure = MAX (max_pressure, ref_pressure);
	  MODEL_MAX_PRESSURE (group, point, pci) = max_pressure;
	}
    }
}

/* Update all successors of INSN, given that INSN has just been scheduled.  */

static void
model_add_successors_to_worklist (struct model_insn_info *insn)
{
  sd_iterator_def sd_it;
  struct model_insn_info *con;
  dep_t dep;

  FOR_EACH_DEP (insn->insn, SD_LIST_FORW, sd_it, dep)
    {
      con = MODEL_INSN_INFO (DEP_CON (dep));
      /* Ignore debug instructions, and instructions from other blocks.  */
      if (con->insn)
	{
	  con->unscheduled_preds--;

	  /* Update the depth field of each true-dependent successor.
	     Increasing the depth gives them a higher priority than
	     before.  */
	  if (DEP_TYPE (dep) == REG_DEP_TRUE && con->depth < insn->depth + 1)
	    {
	      con->depth = insn->depth + 1;
	      if (QUEUE_INDEX (con->insn) == QUEUE_READY)
		model_promote_insn (con);
	    }

	  /* If this is a true dependency, or if there are no remaining
	     dependencies for CON (meaning that CON only had non-true
	     dependencies), make sure that CON is on the worklist.
	     We don't bother otherwise because it would tend to fill the
	     worklist with a lot of low-priority instructions that are not
	     yet ready to issue.  */
	  if ((con->depth > 0 || con->unscheduled_preds == 0)
	      && QUEUE_INDEX (con->insn) == QUEUE_NOWHERE)
	    model_add_to_worklist (con, insn, insn->next);
	}
    }
}

/* Give INSN a higher priority than any current instruction, then give
   unscheduled predecessors of INSN a higher priority still.  If any of
   those predecessors are not on the model worklist, do the same for its
   predecessors, and so on.  */

static void
model_promote_predecessors (struct model_insn_info *insn)
{
  struct model_insn_info *pro, *first;
  sd_iterator_def sd_it;
  dep_t dep;

  if (sched_verbose >= 7)
    fprintf (sched_dump, ";;\t+--- priority of %d = %d, priority of",
	     INSN_UID (insn->insn), model_next_priority);
  insn->model_priority = model_next_priority++;
  model_remove_from_worklist (insn);
  model_add_to_worklist_at (insn, NULL);

  first = NULL;
  for (;;)
    {
      FOR_EACH_DEP (insn->insn, SD_LIST_HARD_BACK, sd_it, dep)
	{
	  pro = MODEL_INSN_INFO (DEP_PRO (dep));
	  /* The first test is to ignore debug instructions, and instructions
	     from other blocks.  */
	  if (pro->insn
	      && pro->model_priority != model_next_priority
	      && QUEUE_INDEX (pro->insn) != QUEUE_SCHEDULED)
	    {
	      pro->model_priority = model_next_priority;
	      if (sched_verbose >= 7)
		fprintf (sched_dump, " %d", INSN_UID (pro->insn));
	      if (QUEUE_INDEX (pro->insn) == QUEUE_READY)
		{
		  /* PRO is already in the worklist, but it now has
		     a higher priority than before.  Move it at the
		     appropriate place.  */
		  model_remove_from_worklist (pro);
		  model_add_to_worklist (pro, NULL, model_worklist);
		}
	      else
		{
		  /* PRO isn't in the worklist.  Recursively process
		     its predecessors until we find one that is.  */
		  pro->next = first;
		  first = pro;
		}
	    }
	}
      if (!first)
	break;
      insn = first;
      first = insn->next;
    }
  if (sched_verbose >= 7)
    fprintf (sched_dump, " = %d\n", model_next_priority);
  model_next_priority++;
}

/* Pick one instruction from model_worklist and process it.  */

static void
model_choose_insn (void)
{
  struct model_insn_info *insn, *fallback;
  int count;

  if (sched_verbose >= 7)
    {
      fprintf (sched_dump, ";;\t+--- worklist:\n");
      insn = model_worklist;
      count = param_max_sched_ready_insns;
      while (count > 0 && insn)
	{
	  fprintf (sched_dump, ";;\t+---   %d [%d, %d, %d, %d]\n",
		   INSN_UID (insn->insn), insn->model_priority,
		   insn->depth + insn->alap, insn->depth,
		   INSN_PRIORITY (insn->insn));
	  count--;
	  insn = insn->next;
	}
    }

  /* Look for a ready instruction whose model_classify_priority is zero
     or negative, picking the highest-priority one.  Adding such an
     instruction to the schedule now should do no harm, and may actually
     do some good.

     Failing that, see whether there is an instruction with the highest
     extant model_priority that is not yet ready, but which would reduce
     pressure if it became ready.  This is designed to catch cases like:

       (set (mem (reg R1)) (reg R2))

     where the instruction is the last remaining use of R1 and where the
     value of R2 is not yet available (or vice versa).  The death of R1
     means that this instruction already reduces pressure.  It is of
     course possible that the computation of R2 involves other registers
     that are hard to kill, but such cases are rare enough for this
     heuristic to be a win in general.

     Failing that, just pick the highest-priority instruction in the
     worklist.  */
  count = param_max_sched_ready_insns;
  insn = model_worklist;
  fallback = 0;
  for (;;)
    {
      if (count == 0 || !insn)
	{
	  insn = fallback ? fallback : model_worklist;
	  break;
	}
      if (insn->unscheduled_preds)
	{
	  if (model_worklist->model_priority == insn->model_priority
	      && !fallback
	      && model_classify_pressure (insn) < 0)
	    fallback = insn;
	}
      else
	{
	  if (model_classify_pressure (insn) <= 0)
	    break;
	}
      count--;
      insn = insn->next;
    }

  if (sched_verbose >= 7 && insn != model_worklist)
    {
      if (insn->unscheduled_preds)
	fprintf (sched_dump, ";;\t+--- promoting insn %d, with dependencies\n",
		 INSN_UID (insn->insn));
      else
	fprintf (sched_dump, ";;\t+--- promoting insn %d, which is ready\n",
		 INSN_UID (insn->insn));
    }
  if (insn->unscheduled_preds)
    /* INSN isn't yet ready to issue.  Give all its predecessors the
       highest priority.  */
    model_promote_predecessors (insn);
  else
    {
      /* INSN is ready.  Add it to the end of model_schedule and
	 process its successors.  */
      model_add_successors_to_worklist (insn);
      model_remove_from_worklist (insn);
      model_add_to_schedule (insn->insn);
      model_record_pressures (insn);
      update_register_pressure (insn->insn);
    }
}

/* Restore all QUEUE_INDEXs to the values that they had before
   model_start_schedule was called.  */

static void
model_reset_queue_indices (void)
{
  unsigned int i;
  rtx_insn *insn;

  FOR_EACH_VEC_ELT (model_schedule, i, insn)
    QUEUE_INDEX (insn) = MODEL_INSN_INFO (insn)->old_queue;
}

/* We have calculated the model schedule and spill costs.  Print a summary
   to sched_dump.  */

static void
model_dump_pressure_summary (void)
{
  int pci, cl;

  fprintf (sched_dump, ";; Pressure summary:");
  for (pci = 0; pci < ira_pressure_classes_num; pci++)
    {
      cl = ira_pressure_classes[pci];
      fprintf (sched_dump, " %s:%d", reg_class_names[cl],
	       model_before_pressure.limits[pci].pressure);
    }
  fprintf (sched_dump, "\n\n");
}

/* Initialize the SCHED_PRESSURE_MODEL information for the current
   scheduling region.  */

static void
model_start_schedule (basic_block bb)
{
  model_next_priority = 1;
  model_schedule.create (sched_max_luid);
  model_insns = XCNEWVEC (struct model_insn_info, sched_max_luid);

  gcc_assert (bb == BLOCK_FOR_INSN (NEXT_INSN (current_sched_info->prev_head)));
  initiate_reg_pressure_info (df_get_live_in (bb));

  model_analyze_insns ();
  model_init_pressure_group (&model_before_pressure);
  while (model_worklist)
    model_choose_insn ();
  gcc_assert (model_num_insns == (int) model_schedule.length ());
  if (sched_verbose >= 2)
    fprintf (sched_dump, "\n");

  model_record_final_pressures (&model_before_pressure);
  model_reset_queue_indices ();

  XDELETEVEC (model_insns);

  model_curr_point = 0;
  initiate_reg_pressure_info (df_get_live_in (bb));
  if (sched_verbose >= 1)
    model_dump_pressure_summary ();
}

/* Free the information associated with GROUP.  */

static void
model_finalize_pressure_group (struct model_pressure_group *group)
{
  XDELETEVEC (group->model);
}

/* Free the information created by model_start_schedule.  */

static void
model_end_schedule (void)
{
  model_finalize_pressure_group (&model_before_pressure);
  model_schedule.release ();
}

/* Prepare reg pressure scheduling for basic block BB.  */
static void
sched_pressure_start_bb (basic_block bb)
{
  /* Set the number of available registers for each class taking into account
     relative probability of current basic block versus function prologue and
     epilogue.
     * If the basic block executes much more often than the prologue/epilogue
     (e.g., inside a hot loop), then cost of spill in the prologue is close to
     nil, so the effective number of available registers is
     (ira_class_hard_regs_num[cl] - fixed_regs_num[cl] - 0).
     * If the basic block executes as often as the prologue/epilogue,
     then spill in the block is as costly as in the prologue, so the effective
     number of available registers is
     (ira_class_hard_regs_num[cl] - fixed_regs_num[cl]
      - call_saved_regs_num[cl]).
     Note that all-else-equal, we prefer to spill in the prologue, since that
     allows "extra" registers for other basic blocks of the function.
     * If the basic block is on the cold path of the function and executes
     rarely, then we should always prefer to spill in the block, rather than
     in the prologue/epilogue.  The effective number of available register is
     (ira_class_hard_regs_num[cl] - fixed_regs_num[cl]
      - call_saved_regs_num[cl]).  */
  {
    int i;
    int entry_freq = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.to_frequency (cfun);
    int bb_freq = bb->count.to_frequency (cfun);

    if (bb_freq == 0)
      {
	if (entry_freq == 0)
	  entry_freq = bb_freq = 1;
      }
    if (bb_freq < entry_freq)
      bb_freq = entry_freq;

    for (i = 0; i < ira_pressure_classes_num; ++i)
      {
	enum reg_class cl = ira_pressure_classes[i];
	sched_class_regs_num[cl] = ira_class_hard_regs_num[cl]
				   - fixed_regs_num[cl];
	sched_class_regs_num[cl]
	  -= (call_saved_regs_num[cl] * entry_freq) / bb_freq;
      }
  }

  if (sched_pressure == SCHED_PRESSURE_MODEL)
    model_start_schedule (bb);
}

/* A structure that holds local state for the loop in schedule_block.  */
struct sched_block_state
{
  /* True if no real insns have been scheduled in the current cycle.  */
  bool first_cycle_insn_p;
  /* True if a shadow insn has been scheduled in the current cycle, which
     means that no more normal insns can be issued.  */
  bool shadows_only_p;
  /* True if we're winding down a modulo schedule, which means that we only
     issue insns with INSN_EXACT_TICK set.  */
  bool modulo_epilogue;
  /* Initialized with the machine's issue rate every cycle, and updated
     by calls to the variable_issue hook.  */
  int can_issue_more;
};

/* INSN is the "currently executing insn".  Launch each insn which was
   waiting on INSN.  READY is the ready list which contains the insns
   that are ready to fire.  CLOCK is the current cycle.  The function
   returns necessary cycle advance after issuing the insn (it is not
   zero for insns in a schedule group).  */

static int
schedule_insn (rtx_insn *insn)
{
  sd_iterator_def sd_it;
  dep_t dep;
  int i;
  int advance = 0;

  if (sched_verbose >= 1)
    {
      struct reg_pressure_data *pressure_info;
      fprintf (sched_dump, ";;\t%3i--> %s %-40s:",
	       clock_var, (*current_sched_info->print_insn) (insn, 1),
	       str_pattern_slim (PATTERN (insn)));

      if (recog_memoized (insn) < 0)
	fprintf (sched_dump, "nothing");
      else
	print_reservation (sched_dump, insn);
      pressure_info = INSN_REG_PRESSURE (insn);
      if (pressure_info != NULL)
	{
	  fputc (':', sched_dump);
	  for (i = 0; i < ira_pressure_classes_num; i++)
	    fprintf (sched_dump, "%s%s%+d(%d)",
		     scheduled_insns.length () > 1
		     && INSN_LUID (insn)
		     < INSN_LUID (scheduled_insns[scheduled_insns.length () - 2]) ? "@" : "",
		     reg_class_names[ira_pressure_classes[i]],
		     pressure_info[i].set_increase, pressure_info[i].change);
	}
      if (sched_pressure == SCHED_PRESSURE_MODEL
	  && model_curr_point < model_num_insns
	  && model_index (insn) == model_curr_point)
	fprintf (sched_dump, ":model %d", model_curr_point);
      fputc ('\n', sched_dump);
    }

  if (sched_pressure == SCHED_PRESSURE_WEIGHTED && !DEBUG_INSN_P (insn))
    update_reg_and_insn_max_reg_pressure (insn);

  /* Scheduling instruction should have all its dependencies resolved and
     should have been removed from the ready list.  */
  gcc_assert (sd_lists_empty_p (insn, SD_LIST_HARD_BACK));

  /* Reset debug insns invalidated by moving this insn.  */
  if (MAY_HAVE_DEBUG_BIND_INSNS && !DEBUG_INSN_P (insn))
    for (sd_it = sd_iterator_start (insn, SD_LIST_BACK);
	 sd_iterator_cond (&sd_it, &dep);)
      {
	rtx_insn *dbg = DEP_PRO (dep);
	struct reg_use_data *use, *next;

	if (DEP_STATUS (dep) & DEP_CANCELLED)
	  {
	    sd_iterator_next (&sd_it);
	    continue;
	  }

	gcc_assert (DEBUG_BIND_INSN_P (dbg));

	if (sched_verbose >= 6)
	  fprintf (sched_dump, ";;\t\tresetting: debug insn %d\n",
		   INSN_UID (dbg));

	/* ??? Rather than resetting the debug insn, we might be able
	   to emit a debug temp before the just-scheduled insn, but
	   this would involve checking that the expression at the
	   point of the debug insn is equivalent to the expression
	   before the just-scheduled insn.  They might not be: the
	   expression in the debug insn may depend on other insns not
	   yet scheduled that set MEMs, REGs or even other debug
	   insns.  It's not clear that attempting to preserve debug
	   information in these cases is worth the effort, given how
	   uncommon these resets are and the likelihood that the debug
	   temps introduced won't survive the schedule change.  */
	INSN_VAR_LOCATION_LOC (dbg) = gen_rtx_UNKNOWN_VAR_LOC ();
	df_insn_rescan (dbg);

	/* Unknown location doesn't use any registers.  */
	for (use = INSN_REG_USE_LIST (dbg); use != NULL; use = next)
	  {
	    struct reg_use_data *prev = use;

	    /* Remove use from the cyclic next_regno_use chain first.  */
	    while (prev->next_regno_use != use)
	      prev = prev->next_regno_use;
	    prev->next_regno_use = use->next_regno_use;
	    next = use->next_insn_use;
	    free (use);
	  }
	INSN_REG_USE_LIST (dbg) = NULL;

	/* We delete rather than resolve these deps, otherwise we
	   crash in sched_free_deps(), because forward deps are
	   expected to be released before backward deps.  */
	sd_delete_dep (sd_it);
      }

  gcc_assert (QUEUE_INDEX (insn) == QUEUE_NOWHERE);
  QUEUE_INDEX (insn) = QUEUE_SCHEDULED;

  if (sched_pressure == SCHED_PRESSURE_MODEL
      && model_curr_point < model_num_insns
      && NONDEBUG_INSN_P (insn))
    {
      if (model_index (insn) == model_curr_point)
	do
	  model_curr_point++;
	while (model_curr_point < model_num_insns
	       && (QUEUE_INDEX (MODEL_INSN (model_curr_point))
		   == QUEUE_SCHEDULED));
      else
	model_recompute (insn);
      model_update_limit_points ();
      update_register_pressure (insn);
      if (sched_verbose >= 2)
	print_curr_reg_pressure ();
    }

  gcc_assert (INSN_TICK (insn) >= MIN_TICK);
  if (INSN_TICK (insn) > clock_var)
    /* INSN has been prematurely moved from the queue to the ready list.
       This is possible only if following flags are set.  */
    gcc_assert (flag_sched_stalled_insns || sched_fusion);

  /* ??? Probably, if INSN is scheduled prematurely, we should leave
     INSN_TICK untouched.  This is a machine-dependent issue, actually.  */
  INSN_TICK (insn) = clock_var;

  check_clobbered_conditions (insn);

  /* Update dependent instructions.  First, see if by scheduling this insn
     now we broke a dependence in a way that requires us to change another
     insn.  */
  for (sd_it = sd_iterator_start (insn, SD_LIST_SPEC_BACK);
       sd_iterator_cond (&sd_it, &dep); sd_iterator_next (&sd_it))
    {
      struct dep_replacement *desc = DEP_REPLACE (dep);
      rtx_insn *pro = DEP_PRO (dep);
      if (QUEUE_INDEX (pro) != QUEUE_SCHEDULED
	  && desc != NULL && desc->insn == pro)
	apply_replacement (dep, false);
    }

  /* Go through and resolve forward dependencies.  */
  for (sd_it = sd_iterator_start (insn, SD_LIST_FORW);
       sd_iterator_cond (&sd_it, &dep);)
    {
      rtx_insn *next = DEP_CON (dep);
      bool cancelled = (DEP_STATUS (dep) & DEP_CANCELLED) != 0;

      /* Resolve the dependence between INSN and NEXT.
	 sd_resolve_dep () moves current dep to another list thus
	 advancing the iterator.  */
      sd_resolve_dep (sd_it);

      if (cancelled)
	{
	  if (must_restore_pattern_p (next, dep))
	    restore_pattern (dep, false);
	  continue;
	}

      /* Don't bother trying to mark next as ready if insn is a debug
	 insn.  If insn is the last hard dependency, it will have
	 already been discounted.  */
      if (DEBUG_INSN_P (insn) && !DEBUG_INSN_P (next))
	continue;

      if (!IS_SPECULATION_BRANCHY_CHECK_P (insn))
	{
	  int effective_cost;

	  effective_cost = try_ready (next);

	  if (effective_cost >= 0
	      && SCHED_GROUP_P (next)
	      && advance < effective_cost)
	    advance = effective_cost;
	}
      else
	/* Check always has only one forward dependence (to the first insn in
	   the recovery block), therefore, this will be executed only once.  */
	{
	  gcc_assert (sd_lists_empty_p (insn, SD_LIST_FORW));
	  fix_recovery_deps (RECOVERY_BLOCK (insn));
	}
    }

  /* Annotate the instruction with issue information -- TImode
     indicates that the instruction is expected not to be able
     to issue on the same cycle as the previous insn.  A machine
     may use this information to decide how the instruction should
     be aligned.  */
  if (issue_rate > 1
      && GET_CODE (PATTERN (insn)) != USE
      && GET_CODE (PATTERN (insn)) != CLOBBER
      && !DEBUG_INSN_P (insn))
    {
      if (reload_completed)
	PUT_MODE (insn, clock_var > last_clock_var ? TImode : VOIDmode);
      last_clock_var = clock_var;
    }

  if (nonscheduled_insns_begin != NULL_RTX)
    /* Indicate to debug counters that INSN is scheduled.  */
    nonscheduled_insns_begin = insn;

  return advance;
}

/* Functions for handling of notes.  */

/* Add note list that ends on FROM_END to the end of TO_ENDP.  */
void
concat_note_lists (rtx_insn *from_end, rtx_insn **to_endp)
{
  rtx_insn *from_start;

  /* It's easy when have nothing to concat.  */
  if (from_end == NULL)
    return;

  /* It's also easy when destination is empty.  */
  if (*to_endp == NULL)
    {
      *to_endp = from_end;
      return;
    }

  from_start = from_end;
  while (PREV_INSN (from_start) != NULL)
    from_start = PREV_INSN (from_start);

  SET_PREV_INSN (from_start) = *to_endp;
  SET_NEXT_INSN (*to_endp) = from_start;
  *to_endp = from_end;
}

/* Delete notes between HEAD and TAIL and put them in the chain
   of notes ended by NOTE_LIST.  */
void
remove_notes (rtx_insn *head, rtx_insn *tail)
{
  rtx_insn *next_tail, *insn, *next;

  note_list = 0;
  if (head == tail && !INSN_P (head))
    return;

  next_tail = NEXT_INSN (tail);
  for (insn = head; insn != next_tail; insn = next)
    {
      next = NEXT_INSN (insn);
      if (!NOTE_P (insn))
	continue;

      switch (NOTE_KIND (insn))
	{
	case NOTE_INSN_BASIC_BLOCK:
	  continue;

	case NOTE_INSN_EPILOGUE_BEG:
	  if (insn != tail)
	    {
	      remove_insn (insn);
	      /* If an insn was split just before the EPILOGUE_BEG note and
		 that split created new basic blocks, we could have a
		 BASIC_BLOCK note here.  Safely advance over it in that case
		 and assert that we land on a real insn.  */
	      if (NOTE_P (next)
		  && NOTE_KIND (next) == NOTE_INSN_BASIC_BLOCK
		  && next != next_tail)
		next = NEXT_INSN (next);
	      gcc_assert (INSN_P (next));
	      add_reg_note (next, REG_SAVE_NOTE,
			    GEN_INT (NOTE_INSN_EPILOGUE_BEG));
	      break;
	    }
	  /* FALLTHRU */

	default:
	  remove_insn (insn);

	  /* Add the note to list that ends at NOTE_LIST.  */
	  SET_PREV_INSN (insn) = note_list;
	  SET_NEXT_INSN (insn) = NULL_RTX;
	  if (note_list)
	    SET_NEXT_INSN (note_list) = insn;
	  note_list = insn;
	  break;
	}

      gcc_assert ((sel_sched_p () || insn != tail) && insn != head);
    }
}

/* A structure to record enough data to allow us to backtrack the scheduler to
   a previous state.  */
struct haifa_saved_data
{
  /* Next entry on the list.  */
  struct haifa_saved_data *next;

  /* Backtracking is associated with scheduling insns that have delay slots.
     DELAY_PAIR points to the structure that contains the insns involved, and
     the number of cycles between them.  */
  struct delay_pair *delay_pair;

  /* Data used by the frontend (e.g. sched-ebb or sched-rgn).  */
  void *fe_saved_data;
  /* Data used by the backend.  */
  void *be_saved_data;

  /* Copies of global state.  */
  int clock_var, last_clock_var;
  struct ready_list ready;
  state_t curr_state;

  rtx_insn *last_scheduled_insn;
  rtx_insn *last_nondebug_scheduled_insn;
  rtx_insn *nonscheduled_insns_begin;
  int cycle_issued_insns;

  /* Copies of state used in the inner loop of schedule_block.  */
  struct sched_block_state sched_block;

  /* We don't need to save q_ptr, as its value is arbitrary and we can set it
     to 0 when restoring.  */
  int q_size;
  rtx_insn_list **insn_queue;

  /* Describe pattern replacements that occurred since this backtrack point
     was queued.  */
  vec<dep_t> replacement_deps;
  vec<int> replace_apply;

  /* A copy of the next-cycle replacement vectors at the time of the backtrack
     point.  */
  vec<dep_t> next_cycle_deps;
  vec<int> next_cycle_apply;
};

/* A record, in reverse order, of all scheduled insns which have delay slots
   and may require backtracking.  */
static struct haifa_saved_data *backtrack_queue;

/* For every dependency of INSN, set the FEEDS_BACKTRACK_INSN bit according
   to SET_P.  */
static void
mark_backtrack_feeds (rtx_insn *insn, int set_p)
{
  sd_iterator_def sd_it;
  dep_t dep;
  FOR_EACH_DEP (insn, SD_LIST_HARD_BACK, sd_it, dep)
    {
      FEEDS_BACKTRACK_INSN (DEP_PRO (dep)) = set_p;
    }
}

/* Save the current scheduler state so that we can backtrack to it
   later if necessary.  PAIR gives the insns that make it necessary to
   save this point.  SCHED_BLOCK is the local state of schedule_block
   that need to be saved.  */
static void
save_backtrack_point (struct delay_pair *pair,
		      struct sched_block_state sched_block)
{
  int i;
  struct haifa_saved_data *save = XNEW (struct haifa_saved_data);

  save->curr_state = xmalloc (dfa_state_size);
  memcpy (save->curr_state, curr_state, dfa_state_size);

  save->ready.first = ready.first;
  save->ready.n_ready = ready.n_ready;
  save->ready.n_debug = ready.n_debug;
  save->ready.veclen = ready.veclen;
  save->ready.vec = XNEWVEC (rtx_insn *, ready.veclen);
  memcpy (save->ready.vec, ready.vec, ready.veclen * sizeof (rtx));

  save->insn_queue = XNEWVEC (rtx_insn_list *, max_insn_queue_index + 1);
  save->q_size = q_size;
  for (i = 0; i <= max_insn_queue_index; i++)
    {
      int q = NEXT_Q_AFTER (q_ptr, i);
      save->insn_queue[i] = copy_INSN_LIST (insn_queue[q]);
    }

  save->clock_var = clock_var;
  save->last_clock_var = last_clock_var;
  save->cycle_issued_insns = cycle_issued_insns;
  save->last_scheduled_insn = last_scheduled_insn;
  save->last_nondebug_scheduled_insn = last_nondebug_scheduled_insn;
  save->nonscheduled_insns_begin = nonscheduled_insns_begin;

  save->sched_block = sched_block;

  save->replacement_deps.create (0);
  save->replace_apply.create (0);
  save->next_cycle_deps = next_cycle_replace_deps.copy ();
  save->next_cycle_apply = next_cycle_apply.copy ();

  if (current_sched_info->save_state)
    save->fe_saved_data = (*current_sched_info->save_state) ();

  if (targetm.sched.alloc_sched_context)
    {
      save->be_saved_data = targetm.sched.alloc_sched_context ();
      targetm.sched.init_sched_context (save->be_saved_data, false);
    }
  else
    save->be_saved_data = NULL;

  save->delay_pair = pair;

  save->next = backtrack_queue;
  backtrack_queue = save;

  while (pair)
    {
      mark_backtrack_feeds (pair->i2, 1);
      INSN_TICK (pair->i2) = INVALID_TICK;
      INSN_EXACT_TICK (pair->i2) = clock_var + pair_delay (pair);
      SHADOW_P (pair->i2) = pair->stages == 0;
      pair = pair->next_same_i1;
    }
}

/* Walk the ready list and all queues. If any insns have unresolved backwards
   dependencies, these must be cancelled deps, broken by predication.  Set or
   clear (depending on SET) the DEP_CANCELLED bit in DEP_STATUS.  */

static void
toggle_cancelled_flags (bool set)
{
  int i;
  sd_iterator_def sd_it;
  dep_t dep;

  if (ready.n_ready > 0)
    {
      rtx_insn **first = ready_lastpos (&ready);
      for (i = 0; i < ready.n_ready; i++)
	FOR_EACH_DEP (first[i], SD_LIST_BACK, sd_it, dep)
	  if (!DEBUG_INSN_P (DEP_PRO (dep)))
	    {
	      if (set)
		DEP_STATUS (dep) |= DEP_CANCELLED;
	      else
		DEP_STATUS (dep) &= ~DEP_CANCELLED;
	    }
    }
  for (i = 0; i <= max_insn_queue_index; i++)
    {
      int q = NEXT_Q_AFTER (q_ptr, i);
      rtx_insn_list *link;
      for (link = insn_queue[q]; link; link = link->next ())
	{
	  rtx_insn *insn = link->insn ();
	  FOR_EACH_DEP (insn, SD_LIST_BACK, sd_it, dep)
	    if (!DEBUG_INSN_P (DEP_PRO (dep)))
	      {
		if (set)
		  DEP_STATUS (dep) |= DEP_CANCELLED;
		else
		  DEP_STATUS (dep) &= ~DEP_CANCELLED;
	      }
	}
    }
}

/* Undo the replacements that have occurred after backtrack point SAVE
   was placed.  */
static void
undo_replacements_for_backtrack (struct haifa_saved_data *save)
{
  while (!save->replacement_deps.is_empty ())
    {
      dep_t dep = save->replacement_deps.pop ();
      int apply_p = save->replace_apply.pop ();

      if (apply_p)
	restore_pattern (dep, true);
      else
	apply_replacement (dep, true);
    }
  save->replacement_deps.release ();
  save->replace_apply.release ();
}

/* Pop entries from the SCHEDULED_INSNS vector up to and including INSN.
   Restore their dependencies to an unresolved state, and mark them as
   queued nowhere.  */

static void
unschedule_insns_until (rtx_insn *insn)
{
  auto_vec<rtx_insn *> recompute_vec;

  /* Make two passes over the insns to be unscheduled.  First, we clear out
     dependencies and other trivial bookkeeping.  */
  for (;;)
    {
      rtx_insn *last;
      sd_iterator_def sd_it;
      dep_t dep;

      last = scheduled_insns.pop ();

      /* This will be changed by restore_backtrack_point if the insn is in
	 any queue.  */
      QUEUE_INDEX (last) = QUEUE_NOWHERE;
      if (last != insn)
	INSN_TICK (last) = INVALID_TICK;

      if (modulo_ii > 0 && INSN_UID (last) < modulo_iter0_max_uid)
	modulo_insns_scheduled--;

      for (sd_it = sd_iterator_start (last, SD_LIST_RES_FORW);
	   sd_iterator_cond (&sd_it, &dep);)
	{
	  rtx_insn *con = DEP_CON (dep);
	  sd_unresolve_dep (sd_it);
	  if (!MUST_RECOMPUTE_SPEC_P (con))
	    {
	      MUST_RECOMPUTE_SPEC_P (con) = 1;
	      recompute_vec.safe_push (con);
	    }
	}

      if (last == insn)
	break;
    }

  /* A second pass, to update ready and speculation status for insns
     depending on the unscheduled ones.  The first pass must have
     popped the scheduled_insns vector up to the point where we
     restart scheduling, as recompute_todo_spec requires it to be
     up-to-date.  */
  while (!recompute_vec.is_empty ())
    {
      rtx_insn *con;

      con = recompute_vec.pop ();
      MUST_RECOMPUTE_SPEC_P (con) = 0;
      if (!sd_lists_empty_p (con, SD_LIST_HARD_BACK))
	{
	  TODO_SPEC (con) = HARD_DEP;
	  INSN_TICK (con) = INVALID_TICK;
	  if (PREDICATED_PAT (con) != NULL_RTX)
	    haifa_change_pattern (con, ORIG_PAT (con));
	}
      else if (QUEUE_INDEX (con) != QUEUE_SCHEDULED)
	TODO_SPEC (con) = recompute_todo_spec (con, true);
    }
}

/* Restore scheduler state from the topmost entry on the backtracking queue.
   PSCHED_BLOCK_P points to the local data of schedule_block that we must
   overwrite with the saved data.
   The caller must already have called unschedule_insns_until.  */

static void
restore_last_backtrack_point (struct sched_block_state *psched_block)
{
  int i;
  struct haifa_saved_data *save = backtrack_queue;

  backtrack_queue = save->next;

  if (current_sched_info->restore_state)
    (*current_sched_info->restore_state) (save->fe_saved_data);

  if (targetm.sched.alloc_sched_context)
    {
      targetm.sched.set_sched_context (save->be_saved_data);
      targetm.sched.free_sched_context (save->be_saved_data);
    }

  /* Do this first since it clobbers INSN_TICK of the involved
     instructions.  */
  undo_replacements_for_backtrack (save);

  /* Clear the QUEUE_INDEX of everything in the ready list or one
     of the queues.  */
  if (ready.n_ready > 0)
    {
      rtx_insn **first = ready_lastpos (&ready);
      for (i = 0; i < ready.n_ready; i++)
	{
	  rtx_insn *insn = first[i];
	  QUEUE_INDEX (insn) = QUEUE_NOWHERE;
	  INSN_TICK (insn) = INVALID_TICK;
	}
    }
  for (i = 0; i <= max_insn_queue_index; i++)
    {
      int q = NEXT_Q_AFTER (q_ptr, i);

      for (rtx_insn_list *link = insn_queue[q]; link; link = link->next ())
	{
	  rtx_insn *x = link->insn ();
	  QUEUE_INDEX (x) = QUEUE_NOWHERE;
	  INSN_TICK (x) = INVALID_TICK;
	}
      free_INSN_LIST_list (&insn_queue[q]);
    }

  free (ready.vec);
  ready = save->ready;

  if (ready.n_ready > 0)
    {
      rtx_insn **first = ready_lastpos (&ready);
      for (i = 0; i < ready.n_ready; i++)
	{
	  rtx_insn *insn = first[i];
	  QUEUE_INDEX (insn) = QUEUE_READY;
	  TODO_SPEC (insn) = recompute_todo_spec (insn, true);
	  INSN_TICK (insn) = save->clock_var;
	}
    }

  q_ptr = 0;
  q_size = save->q_size;
  for (i = 0; i <= max_insn_queue_index; i++)
    {
      int q = NEXT_Q_AFTER (q_ptr, i);

      insn_queue[q] = save->insn_queue[q];

      for (rtx_insn_list *link = insn_queue[q]; link; link = link->next ())
	{
	  rtx_insn *x = link->insn ();
	  QUEUE_INDEX (x) = i;
	  TODO_SPEC (x) = recompute_todo_spec (x, true);
	  INSN_TICK (x) = save->clock_var + i;
	}
    }
  free (save->insn_queue);

  toggle_cancelled_flags (true);

  clock_var = save->clock_var;
  last_clock_var = save->last_clock_var;
  cycle_issued_insns = save->cycle_issued_insns;
  last_scheduled_insn = save->last_scheduled_insn;
  last_nondebug_scheduled_insn = save->last_nondebug_scheduled_insn;
  nonscheduled_insns_begin = save->nonscheduled_insns_begin;

  *psched_block = save->sched_block;

  memcpy (curr_state, save->curr_state, dfa_state_size);
  free (save->curr_state);

  mark_backtrack_feeds (save->delay_pair->i2, 0);

  gcc_assert (next_cycle_replace_deps.is_empty ());
  next_cycle_replace_deps = save->next_cycle_deps.copy ();
  next_cycle_apply = save->next_cycle_apply.copy ();

  free (save);

  for (save = backtrack_queue; save; save = save->next)
    {
      mark_backtrack_feeds (save->delay_pair->i2, 1);
    }
}

/* Discard all data associated with the topmost entry in the backtrack
   queue.  If RESET_TICK is false, we just want to free the data.  If true,
   we are doing this because we discovered a reason to backtrack.  In the
   latter case, also reset the INSN_TICK for the shadow insn.  */
static void
free_topmost_backtrack_point (bool reset_tick)
{
  struct haifa_saved_data *save = backtrack_queue;
  int i;

  backtrack_queue = save->next;

  if (reset_tick)
    {
      struct delay_pair *pair = save->delay_pair;
      while (pair)
	{
	  INSN_TICK (pair->i2) = INVALID_TICK;
	  INSN_EXACT_TICK (pair->i2) = INVALID_TICK;
	  pair = pair->next_same_i1;
	}
      undo_replacements_for_backtrack (save);
    }
  else
    {
      save->replacement_deps.release ();
      save->replace_apply.release ();
    }

  if (targetm.sched.free_sched_context)
    targetm.sched.free_sched_context (save->be_saved_data);
  if (current_sched_info->restore_state)
    free (save->fe_saved_data);
  for (i = 0; i <= max_insn_queue_index; i++)
    free_INSN_LIST_list (&save->insn_queue[i]);
  free (save->insn_queue);
  free (save->curr_state);
  free (save->ready.vec);
  free (save);
}

/* Free the entire backtrack queue.  */
static void
free_backtrack_queue (void)
{
  while (backtrack_queue)
    free_topmost_backtrack_point (false);
}

/* Apply a replacement described by DESC.  If IMMEDIATELY is false, we
   may have to postpone the replacement until the start of the next cycle,
   at which point we will be called again with IMMEDIATELY true.  This is
   only done for machines which have instruction packets with explicit
   parallelism however.  */
static void
apply_replacement (dep_t dep, bool immediately)
{
  struct dep_replacement *desc = DEP_REPLACE (dep);
  if (!immediately && targetm.sched.exposed_pipeline && reload_completed)
    {
      next_cycle_replace_deps.safe_push (dep);
      next_cycle_apply.safe_push (1);
    }
  else
    {
      bool success;

      if (QUEUE_INDEX (desc->insn) == QUEUE_SCHEDULED)
	return;

      if (sched_verbose >= 5)
	fprintf (sched_dump, "applying replacement for insn %d\n",
		 INSN_UID (desc->insn));

      success = validate_change (desc->insn, desc->loc, desc->newval, 0);
      gcc_assert (success);

      rtx_insn *insn = DEP_PRO (dep);

      /* Recompute priority since dependent priorities may have changed.  */
      priority (insn, true);
      update_insn_after_change (desc->insn);

      if ((TODO_SPEC (desc->insn) & (HARD_DEP | DEP_POSTPONED)) == 0)
	fix_tick_ready (desc->insn);

      if (backtrack_queue != NULL)
	{
	  backtrack_queue->replacement_deps.safe_push (dep);
	  backtrack_queue->replace_apply.safe_push (1);
	}
    }
}

/* We have determined that a pattern involved in DEP must be restored.
   If IMMEDIATELY is false, we may have to postpone the replacement
   until the start of the next cycle, at which point we will be called
   again with IMMEDIATELY true.  */
static void
restore_pattern (dep_t dep, bool immediately)
{
  rtx_insn *next = DEP_CON (dep);
  int tick = INSN_TICK (next);

  /* If we already scheduled the insn, the modified version is
     correct.  */
  if (QUEUE_INDEX (next) == QUEUE_SCHEDULED)
    return;

  if (!immediately && targetm.sched.exposed_pipeline && reload_completed)
    {
      next_cycle_replace_deps.safe_push (dep);
      next_cycle_apply.safe_push (0);
      return;
    }


  if (DEP_TYPE (dep) == REG_DEP_CONTROL)
    {
      if (sched_verbose >= 5)
	fprintf (sched_dump, "restoring pattern for insn %d\n",
		 INSN_UID (next));
      haifa_change_pattern (next, ORIG_PAT (next));
    }
  else
    {
      struct dep_replacement *desc = DEP_REPLACE (dep);
      bool success;

      if (sched_verbose >= 5)
	fprintf (sched_dump, "restoring pattern for insn %d\n",
		 INSN_UID (desc->insn));
      tick = INSN_TICK (desc->insn);

      success = validate_change (desc->insn, desc->loc, desc->orig, 0);
      gcc_assert (success);

      rtx_insn *insn = DEP_PRO (dep);

      if (QUEUE_INDEX (insn) != QUEUE_SCHEDULED)
	{
	  /* Recompute priority since dependent priorities may have changed.  */
	  priority (insn, true);
	}

      update_insn_after_change (desc->insn);

      if (backtrack_queue != NULL)
	{
	  backtrack_queue->replacement_deps.safe_push (dep);
	  backtrack_queue->replace_apply.safe_push (0);
	}
    }
  INSN_TICK (next) = tick;
  if (TODO_SPEC (next) == DEP_POSTPONED)
    return;

  if (sd_lists_empty_p (next, SD_LIST_BACK))
    TODO_SPEC (next) = 0;
  else if (!sd_lists_empty_p (next, SD_LIST_HARD_BACK))
    TODO_SPEC (next) = HARD_DEP;
}

/* Perform pattern replacements that were queued up until the next
   cycle.  */
static void
perform_replacements_new_cycle (void)
{
  int i;
  dep_t dep;
  FOR_EACH_VEC_ELT (next_cycle_replace_deps, i, dep)
    {
      int apply_p = next_cycle_apply[i];
      if (apply_p)
	apply_replacement (dep, true);
      else
	restore_pattern (dep, true);
    }
  next_cycle_replace_deps.truncate (0);
  next_cycle_apply.truncate (0);
}

/* Compute INSN_TICK_ESTIMATE for INSN.  PROCESSED is a bitmap of
   instructions we've previously encountered, a set bit prevents
   recursion.  BUDGET is a limit on how far ahead we look, it is
   reduced on recursive calls.  Return true if we produced a good
   estimate, or false if we exceeded the budget.  */
static bool
estimate_insn_tick (bitmap processed, rtx_insn *insn, int budget)
{
  sd_iterator_def sd_it;
  dep_t dep;
  int earliest = INSN_TICK (insn);

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

      if (DEP_STATUS (dep) & DEP_CANCELLED)
	continue;

      if (QUEUE_INDEX (pro) == QUEUE_SCHEDULED)
	gcc_assert (INSN_TICK (pro) + dep_cost (dep) <= INSN_TICK (insn));
      else
	{
	  int cost = dep_cost (dep);
	  if (cost >= budget)
	    return false;
	  if (!bitmap_bit_p (processed, INSN_LUID (pro)))
	    {
	      if (!estimate_insn_tick (processed, pro, budget - cost))
		return false;
	    }
	  gcc_assert (INSN_TICK_ESTIMATE (pro) != INVALID_TICK);
	  t = INSN_TICK_ESTIMATE (pro) + cost;
	  if (earliest == INVALID_TICK || t > earliest)
	    earliest = t;
	}
    }
  bitmap_set_bit (processed, INSN_LUID (insn));
  INSN_TICK_ESTIMATE (insn) = earliest;
  return true;
}

/* Examine the pair of insns in P, and estimate (optimistically, assuming
   infinite resources) the cycle in which the delayed shadow can be issued.
   Return the number of cycles that must pass before the real insn can be
   issued in order to meet this constraint.  */
static int
estimate_shadow_tick (struct delay_pair *p)
{
  auto_bitmap processed;
  int t;
  bool cutoff;

  cutoff = !estimate_insn_tick (processed, p->i2,
				max_insn_queue_index + pair_delay (p));
  if (cutoff)
    return max_insn_queue_index;
  t = INSN_TICK_ESTIMATE (p->i2) - (clock_var + pair_delay (p) + 1);
  if (t > 0)
    return t;
  return 0;
}

/* If INSN has no unresolved backwards dependencies, add it to the schedule and
   recursively resolve all its forward dependencies.  */
static void
resolve_dependencies (rtx_insn *insn)
{
  sd_iterator_def sd_it;
  dep_t dep;

  /* Don't use sd_lists_empty_p; it ignores debug insns.  */
  if (DEPS_LIST_FIRST (INSN_HARD_BACK_DEPS (insn)) != NULL
      || DEPS_LIST_FIRST (INSN_SPEC_BACK_DEPS (insn)) != NULL)
    return;

  if (sched_verbose >= 4)
    fprintf (sched_dump, ";;\tquickly resolving %d\n", INSN_UID (insn));

  if (QUEUE_INDEX (insn) >= 0)
    queue_remove (insn);

  scheduled_insns.safe_push (insn);

  /* Update dependent instructions.  */
  for (sd_it = sd_iterator_start (insn, SD_LIST_FORW);
       sd_iterator_cond (&sd_it, &dep);)
    {
      rtx_insn *next = DEP_CON (dep);

      if (sched_verbose >= 4)
	fprintf (sched_dump, ";;\t\tdep %d against %d\n", INSN_UID (insn),
		 INSN_UID (next));

      /* Resolve the dependence between INSN and NEXT.
	 sd_resolve_dep () moves current dep to another list thus
	 advancing the iterator.  */
      sd_resolve_dep (sd_it);

      if (!IS_SPECULATION_BRANCHY_CHECK_P (insn))
	{
	  resolve_dependencies (next);
	}
      else
	/* Check always has only one forward dependence (to the first insn in
	   the recovery block), therefore, this will be executed only once.  */
	{
	  gcc_assert (sd_lists_empty_p (insn, SD_LIST_FORW));
	}
    }
}


/* Return the head and tail pointers of ebb starting at BEG and ending
   at END.  */
void
get_ebb_head_tail (basic_block beg, basic_block end,
		   rtx_insn **headp, rtx_insn **tailp)
{
  rtx_insn *beg_head = BB_HEAD (beg);
  rtx_insn * beg_tail = BB_END (beg);
  rtx_insn * end_head = BB_HEAD (end);
  rtx_insn * end_tail = BB_END (end);

  /* Don't include any notes or labels at the beginning of the BEG
     basic block, or notes at the end of the END basic blocks.  */

  if (LABEL_P (beg_head))
    beg_head = NEXT_INSN (beg_head);

  while (beg_head != beg_tail)
    if (NOTE_P (beg_head))
      beg_head = NEXT_INSN (beg_head);
    else if (DEBUG_INSN_P (beg_head))
      {
	rtx_insn * note, *next;

	for (note = NEXT_INSN (beg_head);
	     note != beg_tail;
	     note = next)
	  {
	    next = NEXT_INSN (note);
	    if (NOTE_P (note))
	      {
		if (sched_verbose >= 9)
		  fprintf (sched_dump, "reorder %i\n", INSN_UID (note));

		reorder_insns_nobb (note, note, PREV_INSN (beg_head));

		if (BLOCK_FOR_INSN (note) != beg)
		  df_insn_change_bb (note, beg);
	      }
	    else if (!DEBUG_INSN_P (note))
	      break;
	  }

	break;
      }
    else
      break;

  *headp = beg_head;

  if (beg == end)
    end_head = beg_head;
  else if (LABEL_P (end_head))
    end_head = NEXT_INSN (end_head);

  while (end_head != end_tail)
    if (NOTE_P (end_tail))
      end_tail = PREV_INSN (end_tail);
    else if (DEBUG_INSN_P (end_tail))
      {
	rtx_insn * note, *prev;

	for (note = PREV_INSN (end_tail);
	     note != end_head;
	     note = prev)
	  {
	    prev = PREV_INSN (note);
	    if (NOTE_P (note))
	      {
		if (sched_verbose >= 9)
		  fprintf (sched_dump, "reorder %i\n", INSN_UID (note));

		reorder_insns_nobb (note, note, end_tail);

		if (end_tail == BB_END (end))
		  BB_END (end) = note;

		if (BLOCK_FOR_INSN (note) != end)
		  df_insn_change_bb (note, end);
	      }
	    else if (!DEBUG_INSN_P (note))
	      break;
	  }

	break;
      }
    else
      break;

  *tailp = end_tail;
}

/* Return nonzero if there are no real insns in the range [ HEAD, TAIL ].  */

int
no_real_insns_p (const rtx_insn *head, const rtx_insn *tail)
{
  while (head != NEXT_INSN (tail))
    {
      if (!NOTE_P (head) && !LABEL_P (head))
	return 0;
      head = NEXT_INSN (head);
    }
  return 1;
}

/* Restore-other-notes: NOTE_LIST is the end of a chain of notes
   previously found among the insns.  Insert them just before HEAD.  */
rtx_insn *
restore_other_notes (rtx_insn *head, basic_block head_bb)
{
  if (note_list != 0)
    {
      rtx_insn *note_head = note_list;

      if (head)
	head_bb = BLOCK_FOR_INSN (head);
      else
	head = NEXT_INSN (bb_note (head_bb));

      while (PREV_INSN (note_head))
	{
	  set_block_for_insn (note_head, head_bb);
	  note_head = PREV_INSN (note_head);
	}
      /* In the above cycle we've missed this note.  */
      set_block_for_insn (note_head, head_bb);

      SET_PREV_INSN (note_head) = PREV_INSN (head);
      SET_NEXT_INSN (PREV_INSN (head)) = note_head;
      SET_PREV_INSN (head) = note_list;
      SET_NEXT_INSN (note_list) = head;

      if (BLOCK_FOR_INSN (head) != head_bb)
	BB_END (head_bb) = note_list;

      head = note_head;
    }

  return head;
}

/* When we know we are going to discard the schedule due to a failed attempt
   at modulo scheduling, undo all replacements.  */
static void
undo_all_replacements (void)
{
  rtx_insn *insn;
  int i;

  FOR_EACH_VEC_ELT (scheduled_insns, i, insn)
    {
      sd_iterator_def sd_it;
      dep_t dep;

      /* See if we must undo a replacement.  */
      for (sd_it = sd_iterator_start (insn, SD_LIST_RES_FORW);
	   sd_iterator_cond (&sd_it, &dep); sd_iterator_next (&sd_it))
	{
	  struct dep_replacement *desc = DEP_REPLACE (dep);
	  if (desc != NULL)
	    validate_change (desc->insn, desc->loc, desc->orig, 0);
	}
    }
}

/* Return first non-scheduled insn in the current scheduling block.
   This is mostly used for debug-counter purposes.  */
static rtx_insn *
first_nonscheduled_insn (void)
{
  rtx_insn *insn = (nonscheduled_insns_begin != NULL_RTX
		    ? nonscheduled_insns_begin
		    : current_sched_info->prev_head);

  do
    {
      insn = next_nonnote_nondebug_insn (insn);
    }
  while (QUEUE_INDEX (insn) == QUEUE_SCHEDULED);

  return insn;
}

/* Move insns that became ready to fire from queue to ready list.  */

static void
queue_to_ready (struct ready_list *ready)
{
  rtx_insn *insn;
  rtx_insn_list *link;
  rtx_insn *skip_insn;

  q_ptr = NEXT_Q (q_ptr);

  if (dbg_cnt (sched_insn) == false)
    /* If debug counter is activated do not requeue the first
       nonscheduled insn.  */
    skip_insn = first_nonscheduled_insn ();
  else
    skip_insn = NULL;

  /* Add all pending insns that can be scheduled without stalls to the
     ready list.  */
  for (link = insn_queue[q_ptr]; link; link = link->next ())
    {
      insn = link->insn ();
      q_size -= 1;

      if (sched_verbose >= 2)
	fprintf (sched_dump, ";;\t\tQ-->Ready: insn %s: ",
		 (*current_sched_info->print_insn) (insn, 0));

      /* If the ready list is full, delay the insn for 1 cycle.
	 See the comment in schedule_block for the rationale.  */
      if (!reload_completed
	  && (ready->n_ready - ready->n_debug > param_max_sched_ready_insns
	      || (sched_pressure == SCHED_PRESSURE_MODEL
		  /* Limit pressure recalculations to
		     param_max_sched_ready_insns instructions too.  */
		  && model_index (insn) > (model_curr_point
					   + param_max_sched_ready_insns)))
	  && !(sched_pressure == SCHED_PRESSURE_MODEL
	       && model_curr_point < model_num_insns
	       /* Always allow the next model instruction to issue.  */
	       && model_index (insn) == model_curr_point)
	  && !SCHED_GROUP_P (insn)
	  && insn != skip_insn)
	{
	  if (sched_verbose >= 2)
	    fprintf (sched_dump, "keeping in queue, ready full\n");
	  queue_insn (insn, 1, "ready full");
	}
      else
	{
	  ready_add (ready, insn, false);
	  if (sched_verbose >= 2)
	    fprintf (sched_dump, "moving to ready without stalls\n");
        }
    }
  free_INSN_LIST_list (&insn_queue[q_ptr]);

  /* If there are no ready insns, stall until one is ready and add all
     of the pending insns at that point to the ready list.  */
  if (ready->n_ready == 0)
    {
      int stalls;

      for (stalls = 1; stalls <= max_insn_queue_index; stalls++)
	{
	  if ((link = insn_queue[NEXT_Q_AFTER (q_ptr, stalls)]))
	    {
	      for (; link; link = link->next ())
		{
		  insn = link->insn ();
		  q_size -= 1;

		  if (sched_verbose >= 2)
		    fprintf (sched_dump, ";;\t\tQ-->Ready: insn %s: ",
			     (*current_sched_info->print_insn) (insn, 0));

		  ready_add (ready, insn, false);
		  if (sched_verbose >= 2)
		    fprintf (sched_dump, "moving to ready with %d stalls\n", stalls);
		}
	      free_INSN_LIST_list (&insn_queue[NEXT_Q_AFTER (q_ptr, stalls)]);

	      advance_one_cycle ();

	      break;
	    }

	  advance_one_cycle ();
	}

      q_ptr = NEXT_Q_AFTER (q_ptr, stalls);
      clock_var += stalls;
      if (sched_verbose >= 2)
	fprintf (sched_dump, ";;\tAdvancing clock by %d cycle[s] to %d\n",
		 stalls, clock_var);
    }
}

/* Used by early_queue_to_ready.  Determines whether it is "ok" to
   prematurely move INSN from the queue to the ready list.  Currently,
   if a target defines the hook 'is_costly_dependence', this function
   uses the hook to check whether there exist any dependences which are
   considered costly by the target, between INSN and other insns that
   have already been scheduled.  Dependences are checked up to Y cycles
   back, with default Y=1; The flag -fsched-stalled-insns-dep=Y allows
   controlling this value.
   (Other considerations could be taken into account instead (or in
   addition) depending on user flags and target hooks.  */

static bool
ok_for_early_queue_removal (rtx_insn *insn)
{
  if (targetm.sched.is_costly_dependence)
    {
      int n_cycles;
      int i = scheduled_insns.length ();
      for (n_cycles = flag_sched_stalled_insns_dep; n_cycles; n_cycles--)
	{
	  while (i-- > 0)
	    {
	      int cost;

	      rtx_insn *prev_insn = scheduled_insns[i];

	      if (!NOTE_P (prev_insn))
		{
		  dep_t dep;

		  dep = sd_find_dep_between (prev_insn, insn, true);

		  if (dep != NULL)
		    {
		      cost = dep_cost (dep);

		      if (targetm.sched.is_costly_dependence (dep, cost,
				flag_sched_stalled_insns_dep - n_cycles))
			return false;
		    }
		}

	      if (GET_MODE (prev_insn) == TImode) /* end of dispatch group */
		break;
	    }

	  if (i == 0)
	    break;
	}
    }

  return true;
}


/* Remove insns from the queue, before they become "ready" with respect
   to FU latency considerations.  */

static int
early_queue_to_ready (state_t state, struct ready_list *ready)
{
  rtx_insn *insn;
  rtx_insn_list *link;
  rtx_insn_list *next_link;
  rtx_insn_list *prev_link;
  bool move_to_ready;
  int cost;
  state_t temp_state = alloca (dfa_state_size);
  int stalls;
  int insns_removed = 0;

  /*
     Flag '-fsched-stalled-insns=X' determines the aggressiveness of this
     function:

     X == 0: There is no limit on how many queued insns can be removed
             prematurely.  (flag_sched_stalled_insns = -1).

     X >= 1: Only X queued insns can be removed prematurely in each
	     invocation.  (flag_sched_stalled_insns = X).

     Otherwise: Early queue removal is disabled.
         (flag_sched_stalled_insns = 0)
  */

  if (! flag_sched_stalled_insns)
    return 0;

  for (stalls = 0; stalls <= max_insn_queue_index; stalls++)
    {
      if ((link = insn_queue[NEXT_Q_AFTER (q_ptr, stalls)]))
	{
	  if (sched_verbose > 6)
	    fprintf (sched_dump, ";; look at index %d + %d\n", q_ptr, stalls);

	  prev_link = 0;
	  while (link)
	    {
	      next_link = link->next ();
	      insn = link->insn ();
	      if (insn && sched_verbose > 6)
		print_rtl_single (sched_dump, insn);

	      memcpy (temp_state, state, dfa_state_size);
	      if (recog_memoized (insn) < 0)
		/* non-negative to indicate that it's not ready
		   to avoid infinite Q->R->Q->R... */
		cost = 0;
	      else
		cost = state_transition (temp_state, insn);

	      if (sched_verbose >= 6)
		fprintf (sched_dump, "transition cost = %d\n", cost);

	      move_to_ready = false;
	      if (cost < 0)
		{
		  move_to_ready = ok_for_early_queue_removal (insn);
		  if (move_to_ready == true)
		    {
		      /* move from Q to R */
		      q_size -= 1;
		      ready_add (ready, insn, false);

		      if (prev_link)
			XEXP (prev_link, 1) = next_link;
		      else
			insn_queue[NEXT_Q_AFTER (q_ptr, stalls)] = next_link;

		      free_INSN_LIST_node (link);

		      if (sched_verbose >= 2)
			fprintf (sched_dump, ";;\t\tEarly Q-->Ready: insn %s\n",
				 (*current_sched_info->print_insn) (insn, 0));

		      insns_removed++;
		      if (insns_removed == flag_sched_stalled_insns)
			/* Remove no more than flag_sched_stalled_insns insns
			   from Q at a time.  */
			return insns_removed;
		    }
		}

	      if (move_to_ready == false)
		prev_link = link;

	      link = next_link;
	    } /* while link */
	} /* if link */

    } /* for stalls.. */

  return insns_removed;
}


/* Print the ready list for debugging purposes.
   If READY_TRY is non-zero then only print insns that max_issue
   will consider.  */
static void
debug_ready_list_1 (struct ready_list *ready, signed char *ready_try)
{
  rtx_insn **p;
  int i;

  if (ready->n_ready == 0)
    {
      fprintf (sched_dump, "\n");
      return;
    }

  p = ready_lastpos (ready);
  for (i = 0; i < ready->n_ready; i++)
    {
      if (ready_try != NULL && ready_try[ready->n_ready - i - 1])
	continue;

      fprintf (sched_dump, "  %s:%d",
	       (*current_sched_info->print_insn) (p[i], 0),
	       INSN_LUID (p[i]));
      if (sched_pressure != SCHED_PRESSURE_NONE)
	fprintf (sched_dump, "(cost=%d",
		 INSN_REG_PRESSURE_EXCESS_COST_CHANGE (p[i]));
      fprintf (sched_dump, ":prio=%d", INSN_PRIORITY (p[i]));
      if (INSN_TICK (p[i]) > clock_var)
	fprintf (sched_dump, ":delay=%d", INSN_TICK (p[i]) - clock_var);
      if (sched_pressure == SCHED_PRESSURE_MODEL)
	fprintf (sched_dump, ":idx=%d",
		 model_index (p[i]));
      if (sched_pressure != SCHED_PRESSURE_NONE)
	fprintf (sched_dump, ")");
    }
  fprintf (sched_dump, "\n");
}

/* Print the ready list.  Callable from debugger.  */
static void
debug_ready_list (struct ready_list *ready)
{
  debug_ready_list_1 (ready, NULL);
}

/* Search INSN for REG_SAVE_NOTE notes and convert them back into insn
   NOTEs.  This is used for NOTE_INSN_EPILOGUE_BEG, so that sched-ebb
   replaces the epilogue note in the correct basic block.  */
void
reemit_notes (rtx_insn *insn)
{
  rtx note;
  rtx_insn *last = insn;

  for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
    {
      if (REG_NOTE_KIND (note) == REG_SAVE_NOTE)
	{
	  enum insn_note note_type = (enum insn_note) INTVAL (XEXP (note, 0));

	  last = emit_note_before (note_type, last);
	  remove_note (insn, note);
	  df_insn_create_insn_record (last);
	}
    }
}

/* Move INSN.  Reemit notes if needed.  Update CFG, if needed.  */
static void
move_insn (rtx_insn *insn, rtx_insn *last, rtx nt)
{
  if (PREV_INSN (insn) != last)
    {
      basic_block bb;
      rtx_insn *note;
      int jump_p = 0;

      bb = BLOCK_FOR_INSN (insn);

      /* BB_HEAD is either LABEL or NOTE.  */
      gcc_assert (BB_HEAD (bb) != insn);

      if (BB_END (bb) == insn)
	/* If this is last instruction in BB, move end marker one
	   instruction up.  */
	{
	  /* Jumps are always placed at the end of basic block.  */
	  jump_p = control_flow_insn_p (insn);

	  gcc_assert (!jump_p
		      || ((common_sched_info->sched_pass_id == SCHED_RGN_PASS)
			  && IS_SPECULATION_BRANCHY_CHECK_P (insn))
		      || (common_sched_info->sched_pass_id
			  == SCHED_EBB_PASS));

	  gcc_assert (BLOCK_FOR_INSN (PREV_INSN (insn)) == bb);

	  BB_END (bb) = PREV_INSN (insn);
	}

      gcc_assert (BB_END (bb) != last);

      if (jump_p)
	/* We move the block note along with jump.  */
	{
	  gcc_assert (nt);

	  note = NEXT_INSN (insn);
	  while (NOTE_NOT_BB_P (note) && note != nt)
	    note = NEXT_INSN (note);

	  if (note != nt
	      && (LABEL_P (note)
		  || BARRIER_P (note)))
	    note = NEXT_INSN (note);

	  gcc_assert (NOTE_INSN_BASIC_BLOCK_P (note));
	}
      else
	note = insn;

      SET_NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (note);
      SET_PREV_INSN (NEXT_INSN (note)) = PREV_INSN (insn);

      SET_NEXT_INSN (note) = NEXT_INSN (last);
      SET_PREV_INSN (NEXT_INSN (last)) = note;

      SET_NEXT_INSN (last) = insn;
      SET_PREV_INSN (insn) = last;

      bb = BLOCK_FOR_INSN (last);

      if (jump_p)
	{
	  fix_jump_move (insn);

	  if (BLOCK_FOR_INSN (insn) != bb)
	    move_block_after_check (insn);

	  gcc_assert (BB_END (bb) == last);
	}

      df_insn_change_bb (insn, bb);

      /* Update BB_END, if needed.  */
      if (BB_END (bb) == last)
	BB_END (bb) = insn;
    }

  SCHED_GROUP_P (insn) = 0;
}

/* Return true if scheduling INSN will finish current clock cycle.  */
static bool
insn_finishes_cycle_p (rtx_insn *insn)
{
  if (SCHED_GROUP_P (insn))
    /* After issuing INSN, rest of the sched_group will be forced to issue
       in order.  Don't make any plans for the rest of cycle.  */
    return true;

  /* Finishing the block will, apparently, finish the cycle.  */
  if (current_sched_info->insn_finishes_block_p
      && current_sched_info->insn_finishes_block_p (insn))
    return true;

  return false;
}

/* Helper for autopref_multipass_init.  Given a SET in PAT and whether
   we're expecting a memory WRITE or not, check that the insn is relevant to
   the autoprefetcher modelling code.  Return true iff that is the case.
   If it is relevant, record the base register of the memory op in BASE and
   the offset in OFFSET.  */

static bool
analyze_set_insn_for_autopref (rtx pat, bool write, rtx *base, int *offset)
{
  if (GET_CODE (pat) != SET)
    return false;

  rtx mem = write ? SET_DEST (pat) : SET_SRC (pat);
  if (!MEM_P (mem))
    return false;

  struct address_info info;
  decompose_mem_address (&info, mem);

  /* TODO: Currently only (base+const) addressing is supported.  */
  if (info.base == NULL || !REG_P (*info.base)
      || (info.disp != NULL && !CONST_INT_P (*info.disp)))
    return false;

  *base = *info.base;
  *offset = info.disp ? INTVAL (*info.disp) : 0;
  return true;
}

/* Functions to model cache auto-prefetcher.

   Some of the CPUs have cache auto-prefetcher, which /seems/ to initiate
   memory prefetches if it sees instructions with consequitive memory accesses
   in the instruction stream.  Details of such hardware units are not published,
   so we can only guess what exactly is going on there.
   In the scheduler, we model abstract auto-prefetcher.  If there are memory
   insns in the ready list (or the queue) that have same memory base, but
   different offsets, then we delay the insns with larger offsets until insns
   with smaller offsets get scheduled.  If PARAM_SCHED_AUTOPREF_QUEUE_DEPTH
   is "1", then we look at the ready list; if it is N>1, then we also look
   through N-1 queue entries.
   If the param is N>=0, then rank_for_schedule will consider auto-prefetching
   among its heuristics.
   Param value of "-1" disables modelling of the auto-prefetcher.  */

/* Initialize autoprefetcher model data for INSN.  */
static void
autopref_multipass_init (const rtx_insn *insn, int write)
{
  autopref_multipass_data_t data = &INSN_AUTOPREF_MULTIPASS_DATA (insn)[write];

  gcc_assert (data->status == AUTOPREF_MULTIPASS_DATA_UNINITIALIZED);
  data->base = NULL_RTX;
  data->offset = 0;
  /* Set insn entry initialized, but not relevant for auto-prefetcher.  */
  data->status = AUTOPREF_MULTIPASS_DATA_IRRELEVANT;

  rtx pat = PATTERN (insn);

  /* We have a multi-set insn like a load-multiple or store-multiple.
     We care about these as long as all the memory ops inside the PARALLEL
     have the same base register.  We care about the minimum and maximum
     offsets from that base but don't check for the order of those offsets
     within the PARALLEL insn itself.  */
  if (GET_CODE (pat) == PARALLEL)
    {
      int n_elems = XVECLEN (pat, 0);

      int i, offset;
      rtx base, prev_base = NULL_RTX;
      int min_offset = INT_MAX;

      for (i = 0; i < n_elems; i++)
	{
	  rtx set = XVECEXP (pat, 0, i);
	  if (GET_CODE (set) != SET)
	    return;

	  if (!analyze_set_insn_for_autopref (set, write, &base, &offset))
	    return;

	  /* Ensure that all memory operations in the PARALLEL use the same
	     base register.  */
	  if (i > 0 && REGNO (base) != REGNO (prev_base))
	    return;
	  prev_base = base;
	  min_offset = MIN (min_offset, offset);
	}

      /* If we reached here then we have a valid PARALLEL of multiple memory ops
	 with prev_base as the base and min_offset containing the offset.  */
      gcc_assert (prev_base);
      data->base = prev_base;
      data->offset = min_offset;
      data->status = AUTOPREF_MULTIPASS_DATA_NORMAL;
      return;
    }

  /* Otherwise this is a single set memory operation.  */
  rtx set = single_set (insn);
  if (set == NULL_RTX)
    return;

  if (!analyze_set_insn_for_autopref (set, write, &data->base,
				       &data->offset))
    return;

  /* This insn is relevant for the auto-prefetcher.
     The base and offset fields will have been filled in the
     analyze_set_insn_for_autopref call above.  */
  data->status = AUTOPREF_MULTIPASS_DATA_NORMAL;
}

/* Helper function for rank_for_schedule sorting.  */
static int
autopref_rank_for_schedule (const rtx_insn *insn1, const rtx_insn *insn2)
{
  int r = 0;
  for (int write = 0; write < 2 && !r; ++write)
    {
      autopref_multipass_data_t data1
	= &INSN_AUTOPREF_MULTIPASS_DATA (insn1)[write];
      autopref_multipass_data_t data2
	= &INSN_AUTOPREF_MULTIPASS_DATA (insn2)[write];

      if (data1->status == AUTOPREF_MULTIPASS_DATA_UNINITIALIZED)
	autopref_multipass_init (insn1, write);

      if (data2->status == AUTOPREF_MULTIPASS_DATA_UNINITIALIZED)
	autopref_multipass_init (insn2, write);

      int irrel1 = data1->status == AUTOPREF_MULTIPASS_DATA_IRRELEVANT;
      int irrel2 = data2->status == AUTOPREF_MULTIPASS_DATA_IRRELEVANT;

      if (!irrel1 && !irrel2)
	r = data1->offset - data2->offset;
      else
	r = irrel2 - irrel1;
    }

  return r;
}

/* True if header of debug dump was printed.  */
static bool autopref_multipass_dfa_lookahead_guard_started_dump_p;

/* Helper for autopref_multipass_dfa_lookahead_guard.
   Return "1" if INSN1 should be delayed in favor of INSN2.  */
static int
autopref_multipass_dfa_lookahead_guard_1 (const rtx_insn *insn1,
					  const rtx_insn *insn2, int write)
{
  autopref_multipass_data_t data1
    = &INSN_AUTOPREF_MULTIPASS_DATA (insn1)[write];
  autopref_multipass_data_t data2
    = &INSN_AUTOPREF_MULTIPASS_DATA (insn2)[write];

  if (data2->status == AUTOPREF_MULTIPASS_DATA_UNINITIALIZED)
    autopref_multipass_init (insn2, write);
  if (data2->status == AUTOPREF_MULTIPASS_DATA_IRRELEVANT)
    return 0;

  if (rtx_equal_p (data1->base, data2->base)
      && data1->offset > data2->offset)
    {
      if (sched_verbose >= 2)
	{
          if (!autopref_multipass_dfa_lookahead_guard_started_dump_p)
	    {
	      fprintf (sched_dump,
		       ";;\t\tnot trying in max_issue due to autoprefetch "
		       "model: ");
	      autopref_multipass_dfa_lookahead_guard_started_dump_p = true;
	    }

	  fprintf (sched_dump, " %d(%d)", INSN_UID (insn1), INSN_UID (insn2));
	}

      return 1;
    }

  return 0;
}

/* General note:

   We could have also hooked autoprefetcher model into
   first_cycle_multipass_backtrack / first_cycle_multipass_issue hooks
   to enable intelligent selection of "[r1+0]=r2; [r1+4]=r3" on the same cycle
   (e.g., once "[r1+0]=r2" is issued in max_issue(), "[r1+4]=r3" gets
   unblocked).  We don't bother about this yet because target of interest
   (ARM Cortex-A15) can issue only 1 memory operation per cycle.  */

/* Implementation of first_cycle_multipass_dfa_lookahead_guard hook.
   Return "1" if INSN1 should not be considered in max_issue due to
   auto-prefetcher considerations.  */
int
autopref_multipass_dfa_lookahead_guard (rtx_insn *insn1, int ready_index)
{
  int r = 0;

  /* Exit early if the param forbids this or if we're not entering here through
     normal haifa scheduling.  This can happen if selective scheduling is
     explicitly enabled.  */
  if (!insn_queue || param_sched_autopref_queue_depth <= 0)
    return 0;

  if (sched_verbose >= 2 && ready_index == 0)
    autopref_multipass_dfa_lookahead_guard_started_dump_p = false;

  for (int write = 0; write < 2; ++write)
    {
      autopref_multipass_data_t data1
	= &INSN_AUTOPREF_MULTIPASS_DATA (insn1)[write];

      if (data1->status == AUTOPREF_MULTIPASS_DATA_UNINITIALIZED)
	autopref_multipass_init (insn1, write);
      if (data1->status == AUTOPREF_MULTIPASS_DATA_IRRELEVANT)
	continue;

      if (ready_index == 0
	  && data1->status == AUTOPREF_MULTIPASS_DATA_DONT_DELAY)
	/* We allow only a single delay on priviledged instructions.
	   Doing otherwise would cause infinite loop.  */
	{
	  if (sched_verbose >= 2)
	    {
	      if (!autopref_multipass_dfa_lookahead_guard_started_dump_p)
		{
		  fprintf (sched_dump,
			   ";;\t\tnot trying in max_issue due to autoprefetch "
			   "model: ");
		  autopref_multipass_dfa_lookahead_guard_started_dump_p = true;
		}

	      fprintf (sched_dump, " *%d*", INSN_UID (insn1));
	    }
	  continue;
	}

      for (int i2 = 0; i2 < ready.n_ready; ++i2)
	{
	  rtx_insn *insn2 = get_ready_element (i2);
	  if (insn1 == insn2)
	    continue;
	  r = autopref_multipass_dfa_lookahead_guard_1 (insn1, insn2, write);
	  if (r)
	    {
	      if (ready_index == 0)
		{
		  r = -1;
		  data1->status = AUTOPREF_MULTIPASS_DATA_DONT_DELAY;
		}
	      goto finish;
	    }
	}

      if (param_sched_autopref_queue_depth == 1)
	continue;

      /* Everything from the current queue slot should have been moved to
	 the ready list.  */
      gcc_assert (insn_queue[NEXT_Q_AFTER (q_ptr, 0)] == NULL_RTX);

      int n_stalls = param_sched_autopref_queue_depth - 1;
      if (n_stalls > max_insn_queue_index)
	n_stalls = max_insn_queue_index;

      for (int stalls = 1; stalls <= n_stalls; ++stalls)
	{
	  for (rtx_insn_list *link = insn_queue[NEXT_Q_AFTER (q_ptr, stalls)];
	       link != NULL_RTX;
	       link = link->next ())
	    {
	      rtx_insn *insn2 = link->insn ();
	      r = autopref_multipass_dfa_lookahead_guard_1 (insn1, insn2,
							    write);
	      if (r)
		{
		  /* Queue INSN1 until INSN2 can issue.  */
		  r = -stalls;
		  if (ready_index == 0)
		    data1->status = AUTOPREF_MULTIPASS_DATA_DONT_DELAY;
		  goto finish;
		}
	    }
	}
    }

    finish:
  if (sched_verbose >= 2
      && autopref_multipass_dfa_lookahead_guard_started_dump_p
      && (ready_index == ready.n_ready - 1 || r < 0))
    /* This does not /always/ trigger.  We don't output EOL if the last
       insn is not recognized (INSN_CODE < 0) and lookahead_guard is not
       called.  We can live with this.  */
    fprintf (sched_dump, "\n");

  return r;
}

/* Define type for target data used in multipass scheduling.  */
#ifndef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DATA_T
# define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DATA_T int
#endif
typedef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DATA_T first_cycle_multipass_data_t;

/* The following structure describe an entry of the stack of choices.  */
struct choice_entry
{
  /* Ordinal number of the issued insn in the ready queue.  */
  int index;
  /* The number of the rest insns whose issues we should try.  */
  int rest;
  /* The number of issued essential insns.  */
  int n;
  /* State after issuing the insn.  */
  state_t state;
  /* Target-specific data.  */
  first_cycle_multipass_data_t target_data;
};

/* The following array is used to implement a stack of choices used in
   function max_issue.  */
static struct choice_entry *choice_stack;

/* This holds the value of the target dfa_lookahead hook.  */
int dfa_lookahead;

/* The following variable value is maximal number of tries of issuing
   insns for the first cycle multipass insn scheduling.  We define
   this value as constant*(DFA_LOOKAHEAD**ISSUE_RATE).  We would not
   need this constraint if all real insns (with non-negative codes)
   had reservations because in this case the algorithm complexity is
   O(DFA_LOOKAHEAD**ISSUE_RATE).  Unfortunately, the dfa descriptions
   might be incomplete and such insn might occur.  For such
   descriptions, the complexity of algorithm (without the constraint)
   could achieve DFA_LOOKAHEAD ** N , where N is the queue length.  */
static int max_lookahead_tries;

/* The following function returns maximal (or close to maximal) number
   of insns which can be issued on the same cycle and one of which
   insns is insns with the best rank (the first insn in READY).  To
   make this function tries different samples of ready insns.  READY
   is current queue `ready'.  Global array READY_TRY reflects what
   insns are already issued in this try.  The function stops immediately,
   if it reached the such a solution, that all instruction can be issued.
   INDEX will contain index of the best insn in READY.  The following
   function is used only for first cycle multipass scheduling.

   PRIVILEGED_N >= 0

   This function expects recognized insns only.  All USEs,
   CLOBBERs, etc must be filtered elsewhere.  */
int
max_issue (struct ready_list *ready, int privileged_n, state_t state,
	   bool first_cycle_insn_p, int *index)
{
  int n, i, all, n_ready, best, delay, tries_num;
  int more_issue;
  struct choice_entry *top;
  rtx_insn *insn;

  if (sched_fusion)
    return 0;

  n_ready = ready->n_ready;
  gcc_assert (dfa_lookahead >= 1 && privileged_n >= 0
	      && privileged_n <= n_ready);

  /* Init MAX_LOOKAHEAD_TRIES.  */
  if (max_lookahead_tries == 0)
    {
      max_lookahead_tries = 100;
      for (i = 0; i < issue_rate; i++)
	max_lookahead_tries *= dfa_lookahead;
    }

  /* Init max_points.  */
  more_issue = issue_rate - cycle_issued_insns;
  gcc_assert (more_issue >= 0);

  /* The number of the issued insns in the best solution.  */
  best = 0;

  top = choice_stack;

  /* Set initial state of the search.  */
  memcpy (top->state, state, dfa_state_size);
  top->rest = dfa_lookahead;
  top->n = 0;
  if (targetm.sched.first_cycle_multipass_begin)
    targetm.sched.first_cycle_multipass_begin (&top->target_data,
					       ready_try, n_ready,
					       first_cycle_insn_p);

  /* Count the number of the insns to search among.  */
  for (all = i = 0; i < n_ready; i++)
    if (!ready_try [i])
      all++;

  if (sched_verbose >= 2)
    {
      fprintf (sched_dump, ";;\t\tmax_issue among %d insns:", all);
      debug_ready_list_1 (ready, ready_try);
    }

  /* I is the index of the insn to try next.  */
  i = 0;
  tries_num = 0;
  for (;;)
    {
      if (/* If we've reached a dead end or searched enough of what we have
	     been asked...  */
	  top->rest == 0
	  /* or have nothing else to try...  */
	  || i >= n_ready
	  /* or should not issue more.  */
	  || top->n >= more_issue)
	{
	  /* ??? (... || i == n_ready).  */
	  gcc_assert (i <= n_ready);

	  /* We should not issue more than issue_rate instructions.  */
	  gcc_assert (top->n <= more_issue);

	  if (top == choice_stack)
	    break;

	  if (best < top - choice_stack)
	    {
	      if (privileged_n)
		{
		  n = privileged_n;
		  /* Try to find issued privileged insn.  */
		  while (n && !ready_try[--n])
		    ;
		}

	      if (/* If all insns are equally good...  */
		  privileged_n == 0
		  /* Or a privileged insn will be issued.  */
		  || ready_try[n])
		/* Then we have a solution.  */
		{
		  best = top - choice_stack;
		  /* This is the index of the insn issued first in this
		     solution.  */
		  *index = choice_stack [1].index;
		  if (top->n == more_issue || best == all)
		    break;
		}
	    }

	  /* Set ready-list index to point to the last insn
	     ('i++' below will advance it to the next insn).  */
	  i = top->index;

	  /* Backtrack.  */
	  ready_try [i] = 0;

	  if (targetm.sched.first_cycle_multipass_backtrack)
	    targetm.sched.first_cycle_multipass_backtrack (&top->target_data,
							   ready_try, n_ready);

	  top--;
	  memcpy (state, top->state, dfa_state_size);
	}
      else if (!ready_try [i])
	{
	  tries_num++;
	  if (tries_num > max_lookahead_tries)
	    break;
	  insn = ready_element (ready, i);
	  delay = state_transition (state, insn);
	  if (delay < 0)
	    {
	      if (state_dead_lock_p (state)
		  || insn_finishes_cycle_p (insn))
		/* We won't issue any more instructions in the next
		   choice_state.  */
		top->rest = 0;
	      else
		top->rest--;

	      n = top->n;
	      if (memcmp (top->state, state, dfa_state_size) != 0)
		n++;

	      /* Advance to the next choice_entry.  */
	      top++;
	      /* Initialize it.  */
	      top->rest = dfa_lookahead;
	      top->index = i;
	      top->n = n;
	      memcpy (top->state, state, dfa_state_size);
	      ready_try [i] = 1;

	      if (targetm.sched.first_cycle_multipass_issue)
		targetm.sched.first_cycle_multipass_issue (&top->target_data,
							   ready_try, n_ready,
							   insn,
							   &((top - 1)
							     ->target_data));

	      i = -1;
	    }
	}

      /* Increase ready-list index.  */
      i++;
    }

  if (targetm.sched.first_cycle_multipass_end)
    targetm.sched.first_cycle_multipass_end (best != 0
					     ? &choice_stack[1].target_data
					     : NULL);

  /* Restore the original state of the DFA.  */
  memcpy (state, choice_stack->state, dfa_state_size);

  return best;
}

/* The following function chooses insn from READY and modifies
   READY.  The following function is used only for first
   cycle multipass scheduling.
   Return:
   -1 if cycle should be advanced,
   0 if INSN_PTR is set to point to the desirable insn,
   1 if choose_ready () should be restarted without advancing the cycle.  */
static int
choose_ready (struct ready_list *ready, bool first_cycle_insn_p,
	      rtx_insn **insn_ptr)
{
  if (dbg_cnt (sched_insn) == false)
    {
      if (nonscheduled_insns_begin == NULL_RTX)
	nonscheduled_insns_begin = current_sched_info->prev_head;

      rtx_insn *insn = first_nonscheduled_insn ();

      if (QUEUE_INDEX (insn) == QUEUE_READY)
	/* INSN is in the ready_list.  */
	{
	  ready_remove_insn (insn);
	  *insn_ptr = insn;
	  return 0;
	}

      /* INSN is in the queue.  Advance cycle to move it to the ready list.  */
      gcc_assert (QUEUE_INDEX (insn) >= 0);
      return -1;
    }

  if (dfa_lookahead <= 0 || SCHED_GROUP_P (ready_element (ready, 0))
      || DEBUG_INSN_P (ready_element (ready, 0)))
    {
      if (targetm.sched.dispatch (NULL, IS_DISPATCH_ON))
	*insn_ptr = ready_remove_first_dispatch (ready);
      else
	*insn_ptr = ready_remove_first (ready);

      return 0;
    }
  else
    {
      /* Try to choose the best insn.  */
      int index = 0, i;
      rtx_insn *insn;

      insn = ready_element (ready, 0);
      if (INSN_CODE (insn) < 0)
	{
	  *insn_ptr = ready_remove_first (ready);
	  return 0;
	}

      /* Filter the search space.  */
      for (i = 0; i < ready->n_ready; i++)
	{
	  ready_try[i] = 0;

	  insn = ready_element (ready, i);

	  /* If this insn is recognizable we should have already
	     recognized it earlier.
	     ??? Not very clear where this is supposed to be done.
	     See dep_cost_1.  */
	  gcc_checking_assert (INSN_CODE (insn) >= 0
			       || recog_memoized (insn) < 0);
	  if (INSN_CODE (insn) < 0)
	    {
	      /* Non-recognized insns at position 0 are handled above.  */
	      gcc_assert (i > 0);
	      ready_try[i] = 1;
	      continue;
	    }

	  if (targetm.sched.first_cycle_multipass_dfa_lookahead_guard)
	    {
	      ready_try[i]
		= (targetm.sched.first_cycle_multipass_dfa_lookahead_guard
		    (insn, i));

	      if (ready_try[i] < 0)
		/* Queue instruction for several cycles.
		   We need to restart choose_ready as we have changed
		   the ready list.  */
		{
		  change_queue_index (insn, -ready_try[i]);
		  return 1;
		}

	      /* Make sure that we didn't end up with 0'th insn filtered out.
		 Don't be tempted to make life easier for backends and just
		 requeue 0'th insn if (ready_try[0] == 0) and restart
		 choose_ready.  Backends should be very considerate about
		 requeueing instructions -- especially the highest priority
		 one at position 0.  */
	      gcc_assert (ready_try[i] == 0 || i > 0);
	      if (ready_try[i])
		continue;
	    }

	  gcc_assert (ready_try[i] == 0);
	  /* INSN made it through the scrutiny of filters!  */
	}

      if (max_issue (ready, 1, curr_state, first_cycle_insn_p, &index) == 0)
	{
	  *insn_ptr = ready_remove_first (ready);
	  if (sched_verbose >= 4)
	    fprintf (sched_dump, ";;\t\tChosen insn (but can't issue) : %s \n",
                     (*current_sched_info->print_insn) (*insn_ptr, 0));
	  return 0;
	}
      else
	{
	  if (sched_verbose >= 4)
	    fprintf (sched_dump, ";;\t\tChosen insn : %s\n",
		     (*current_sched_info->print_insn)
		     (ready_element (ready, index), 0));

	  *insn_ptr = ready_remove (ready, index);
	  return 0;
	}
    }
}

/* This function is called when we have successfully scheduled a
   block.  It uses the schedule stored in the scheduled_insns vector
   to rearrange the RTL.  PREV_HEAD is used as the anchor to which we
   append the scheduled insns; TAIL is the insn after the scheduled
   block.  TARGET_BB is the argument passed to schedule_block.  */

static void
commit_schedule (rtx_insn *prev_head, rtx_insn *tail, basic_block *target_bb)
{
  unsigned int i;
  rtx_insn *insn;

  last_scheduled_insn = prev_head;
  for (i = 0;
       scheduled_insns.iterate (i, &insn);
       i++)
    {
      if (control_flow_insn_p (last_scheduled_insn)
	  || current_sched_info->advance_target_bb (*target_bb, insn))
	{
	  *target_bb = current_sched_info->advance_target_bb (*target_bb, 0);

	  if (sched_verbose)
	    {
	      rtx_insn *x;

	      x = next_real_insn (last_scheduled_insn);
	      gcc_assert (x);
	      dump_new_block_header (1, *target_bb, x, tail);
	    }

	  last_scheduled_insn = bb_note (*target_bb);
	}

      if (current_sched_info->begin_move_insn)
	(*current_sched_info->begin_move_insn) (insn, last_scheduled_insn);
      move_insn (insn, last_scheduled_insn,
		 current_sched_info->next_tail);
      if (!DEBUG_INSN_P (insn))
	reemit_notes (insn);
      last_scheduled_insn = insn;
    }

  scheduled_insns.truncate (0);
}

/* Examine all insns on the ready list and queue those which can't be
   issued in this cycle.  TEMP_STATE is temporary scheduler state we
   can use as scratch space.  If FIRST_CYCLE_INSN_P is true, no insns
   have been issued for the current cycle, which means it is valid to
   issue an asm statement.

   If SHADOWS_ONLY_P is true, we eliminate all real insns and only
   leave those for which SHADOW_P is true.  If MODULO_EPILOGUE is true,
   we only leave insns which have an INSN_EXACT_TICK.  */

static void
prune_ready_list (state_t temp_state, bool first_cycle_insn_p,
		  bool shadows_only_p, bool modulo_epilogue_p)
{
  int i, pass;
  bool sched_group_found = false;
  int min_cost_group = 0;

  if (sched_fusion)
    return;

  for (i = 0; i < ready.n_ready; i++)
    {
      rtx_insn *insn = ready_element (&ready, i);
      if (SCHED_GROUP_P (insn))
	{
	  sched_group_found = true;
	  break;
	}
    }

  /* Make two passes if there's a SCHED_GROUP_P insn; make sure to handle
     such an insn first and note its cost.  If at least one SCHED_GROUP_P insn
     gets queued, then all other insns get queued for one cycle later.  */
  for (pass = sched_group_found ? 0 : 1; pass < 2; )
    {
      int n = ready.n_ready;
      for (i = 0; i < n; i++)
	{
	  rtx_insn *insn = ready_element (&ready, i);
	  int cost = 0;
	  const char *reason = "resource conflict";

	  if (DEBUG_INSN_P (insn))
	    continue;

	  if (sched_group_found && !SCHED_GROUP_P (insn)
	      && ((pass == 0) || (min_cost_group >= 1)))
	    {
	      if (pass == 0)
		continue;
	      cost = min_cost_group;
	      reason = "not in sched group";
	    }
	  else if (modulo_epilogue_p
		   && INSN_EXACT_TICK (insn) == INVALID_TICK)
	    {
	      cost = max_insn_queue_index;
	      reason = "not an epilogue insn";
	    }
	  else if (shadows_only_p && !SHADOW_P (insn))
	    {
	      cost = 1;
	      reason = "not a shadow";
	    }
	  else if (recog_memoized (insn) < 0)
	    {
	      if (!first_cycle_insn_p
		  && (GET_CODE (PATTERN (insn)) == ASM_INPUT
		      || asm_noperands (PATTERN (insn)) >= 0))
		cost = 1;
	      reason = "asm";
	    }
	  else if (sched_pressure != SCHED_PRESSURE_NONE)
	    {
	      if (sched_pressure == SCHED_PRESSURE_MODEL
		  && INSN_TICK (insn) <= clock_var)
		{
		  memcpy (temp_state, curr_state, dfa_state_size);
		  if (state_transition (temp_state, insn) >= 0)
		    INSN_TICK (insn) = clock_var + 1;
		}
	      cost = 0;
	    }
	  else
	    {
	      int delay_cost = 0;

	      if (delay_htab)
		{
		  struct delay_pair *delay_entry;
		  delay_entry
		    = delay_htab->find_with_hash (insn,
						  htab_hash_pointer (insn));
		  while (delay_entry && delay_cost == 0)
		    {
		      delay_cost = estimate_shadow_tick (delay_entry);
		      if (delay_cost > max_insn_queue_index)
			delay_cost = max_insn_queue_index;
		      delay_entry = delay_entry->next_same_i1;
		    }
		}

	      memcpy (temp_state, curr_state, dfa_state_size);
	      cost = state_transition (temp_state, insn);
	      if (cost < 0)
		cost = 0;
	      else if (cost == 0)
		cost = 1;
	      if (cost < delay_cost)
		{
		  cost = delay_cost;
		  reason = "shadow tick";
		}
	    }
	  if (cost >= 1)
	    {
	      if (SCHED_GROUP_P (insn) && cost > min_cost_group)
		min_cost_group = cost;
	      ready_remove (&ready, i);
	      /* Normally we'd want to queue INSN for COST cycles.  However,
		 if SCHED_GROUP_P is set, then we must ensure that nothing
		 else comes between INSN and its predecessor.  If there is
		 some other insn ready to fire on the next cycle, then that
		 invariant would be broken.

		 So when SCHED_GROUP_P is set, just queue this insn for a
		 single cycle.  */
	      queue_insn (insn, SCHED_GROUP_P (insn) ? 1 : cost, reason);
	      if (i + 1 < n)
		break;
	    }
	}
      if (i == n)
	pass++;
    }
}

/* Called when we detect that the schedule is impossible.  We examine the
   backtrack queue to find the earliest insn that caused this condition.  */

static struct haifa_saved_data *
verify_shadows (void)
{
  struct haifa_saved_data *save, *earliest_fail = NULL;
  for (save = backtrack_queue; save; save = save->next)
    {
      int t;
      struct delay_pair *pair = save->delay_pair;
      rtx_insn *i1 = pair->i1;

      for (; pair; pair = pair->next_same_i1)
	{
	  rtx_insn *i2 = pair->i2;

	  if (QUEUE_INDEX (i2) == QUEUE_SCHEDULED)
	    continue;

	  t = INSN_TICK (i1) + pair_delay (pair);
	  if (t < clock_var)
	    {
	      if (sched_verbose >= 2)
		fprintf (sched_dump,
			 ";;\t\tfailed delay requirements for %d/%d (%d->%d)"
			 ", not ready\n",
			 INSN_UID (pair->i1), INSN_UID (pair->i2),
			 INSN_TICK (pair->i1), INSN_EXACT_TICK (pair->i2));
	      earliest_fail = save;
	      break;
	    }
	  if (QUEUE_INDEX (i2) >= 0)
	    {
	      int queued_for = INSN_TICK (i2);

	      if (t < queued_for)
		{
		  if (sched_verbose >= 2)
		    fprintf (sched_dump,
			     ";;\t\tfailed delay requirements for %d/%d"
			     " (%d->%d), queued too late\n",
			     INSN_UID (pair->i1), INSN_UID (pair->i2),
			     INSN_TICK (pair->i1), INSN_EXACT_TICK (pair->i2));
		  earliest_fail = save;
		  break;
		}
	    }
	}
    }

  return earliest_fail;
}

/* Print instructions together with useful scheduling information between
   HEAD and TAIL (inclusive).  */
static void
dump_insn_stream (rtx_insn *head, rtx_insn *tail)
{
  fprintf (sched_dump, ";;\t| insn | prio |\n");

  rtx_insn *next_tail = NEXT_INSN (tail);
  for (rtx_insn *insn = head; insn != next_tail; insn = NEXT_INSN (insn))
    {
      int priority = NOTE_P (insn) ? 0 : INSN_PRIORITY (insn);
      const char *pattern = (NOTE_P (insn)
			     ? "note"
			     : str_pattern_slim (PATTERN (insn)));

      fprintf (sched_dump, ";;\t| %4d | %4d | %-30s ",
	       INSN_UID (insn), priority, pattern);

      if (sched_verbose >= 4)
	{
	  if (NOTE_P (insn) || LABEL_P (insn) || recog_memoized (insn) < 0)
	    fprintf (sched_dump, "nothing");
	  else
	    print_reservation (sched_dump, insn);
	}
      fprintf (sched_dump, "\n");
    }
}

/* Use forward list scheduling to rearrange insns of block pointed to by
   TARGET_BB, possibly bringing insns from subsequent blocks in the same
   region.  */

bool
schedule_block (basic_block *target_bb, state_t init_state)
{
  int i;
  bool success = modulo_ii == 0;
  struct sched_block_state ls;
  state_t temp_state = NULL;  /* It is used for multipass scheduling.  */
  int sort_p, advance, start_clock_var;

  /* Head/tail info for this block.  */
  rtx_insn *prev_head = current_sched_info->prev_head;
  rtx_insn *next_tail = current_sched_info->next_tail;
  rtx_insn *head = NEXT_INSN (prev_head);
  rtx_insn *tail = PREV_INSN (next_tail);

  if ((current_sched_info->flags & DONT_BREAK_DEPENDENCIES) == 0
      && sched_pressure != SCHED_PRESSURE_MODEL && !sched_fusion)
    find_modifiable_mems (head, tail);

  /* We used to have code to avoid getting parameters moved from hard
     argument registers into pseudos.

     However, it was removed when it proved to be of marginal benefit
     and caused problems because schedule_block and compute_forward_dependences
     had different notions of what the "head" insn was.  */

  gcc_assert (head != tail || INSN_P (head));

  haifa_recovery_bb_recently_added_p = false;

  backtrack_queue = NULL;

  /* Debug info.  */
  if (sched_verbose)
    {
      dump_new_block_header (0, *target_bb, head, tail);

      if (sched_verbose >= 2)
	{
	  dump_insn_stream (head, tail);
	  memset (&rank_for_schedule_stats, 0,
		  sizeof (rank_for_schedule_stats));
	}
    }

  if (init_state == NULL)
    state_reset (curr_state);
  else
    memcpy (curr_state, init_state, dfa_state_size);

  /* Clear the ready list.  */
  ready.first = ready.veclen - 1;
  ready.n_ready = 0;
  ready.n_debug = 0;

  /* It is used for first cycle multipass scheduling.  */
  temp_state = alloca (dfa_state_size);

  if (targetm.sched.init)
    targetm.sched.init (sched_dump, sched_verbose, ready.veclen);

  /* We start inserting insns after PREV_HEAD.  */
  last_scheduled_insn = prev_head;
  last_nondebug_scheduled_insn = NULL;
  nonscheduled_insns_begin = NULL;

  gcc_assert ((NOTE_P (last_scheduled_insn)
	       || DEBUG_INSN_P (last_scheduled_insn))
	      && BLOCK_FOR_INSN (last_scheduled_insn) == *target_bb);

  /* Initialize INSN_QUEUE.  Q_SIZE is the total number of insns in the
     queue.  */
  q_ptr = 0;
  q_size = 0;

  insn_queue = XALLOCAVEC (rtx_insn_list *, max_insn_queue_index + 1);
  memset (insn_queue, 0, (max_insn_queue_index + 1) * sizeof (rtx));

  /* Start just before the beginning of time.  */
  clock_var = -1;

  /* We need queue and ready lists and clock_var be initialized
     in try_ready () (which is called through init_ready_list ()).  */
  (*current_sched_info->init_ready_list) ();

  if (sched_pressure)
    sched_pressure_start_bb (*target_bb);

  /* The algorithm is O(n^2) in the number of ready insns at any given
     time in the worst case.  Before reload we are more likely to have
     big lists so truncate them to a reasonable size.  */
  if (!reload_completed
      && ready.n_ready - ready.n_debug > param_max_sched_ready_insns)
    {
      ready_sort_debug (&ready);
      ready_sort_real (&ready);

      /* Find first free-standing insn past param_max_sched_ready_insns.
         If there are debug insns, we know they're first.  */
      for (i = param_max_sched_ready_insns + ready.n_debug; i < ready.n_ready;
	   i++)
	if (!SCHED_GROUP_P (ready_element (&ready, i)))
	  break;

      if (sched_verbose >= 2)
	{
	  fprintf (sched_dump,
		   ";;\t\tReady list on entry: %d insns:  ", ready.n_ready);
	  debug_ready_list (&ready);
	  fprintf (sched_dump,
		   ";;\t\t before reload => truncated to %d insns\n", i);
	}

      /* Delay all insns past it for 1 cycle.  If debug counter is
	 activated make an exception for the insn right after
	 nonscheduled_insns_begin.  */
      {
	rtx_insn *skip_insn;

	if (dbg_cnt (sched_insn) == false)
	  skip_insn = first_nonscheduled_insn ();
	else
	  skip_insn = NULL;

	while (i < ready.n_ready)
	  {
	    rtx_insn *insn;

	    insn = ready_remove (&ready, i);

	    if (insn != skip_insn)
	      queue_insn (insn, 1, "list truncated");
	  }
	if (skip_insn)
	  ready_add (&ready, skip_insn, true);
      }
    }

  /* Now we can restore basic block notes and maintain precise cfg.  */
  restore_bb_notes (*target_bb);

  last_clock_var = -1;

  advance = 0;

  gcc_assert (scheduled_insns.length () == 0);
  sort_p = TRUE;
  must_backtrack = false;
  modulo_insns_scheduled = 0;

  ls.modulo_epilogue = false;
  ls.first_cycle_insn_p = true;

  /* Loop until all the insns in BB are scheduled.  */
  while ((*current_sched_info->schedule_more_p) ())
    {
      perform_replacements_new_cycle ();
      do
	{
	  start_clock_var = clock_var;

	  clock_var++;

	  advance_one_cycle ();

	  /* Add to the ready list all pending insns that can be issued now.
	     If there are no ready insns, increment clock until one
	     is ready and add all pending insns at that point to the ready
	     list.  */
	  queue_to_ready (&ready);

	  gcc_assert (ready.n_ready);

	  if (sched_verbose >= 2)
	    {
	      fprintf (sched_dump, ";;\t\tReady list after queue_to_ready:");
	      debug_ready_list (&ready);
	    }
	  advance -= clock_var - start_clock_var;
	}
      while (advance > 0);

      if (ls.modulo_epilogue)
	{
	  int stage = clock_var / modulo_ii;
	  if (stage > modulo_last_stage * 2 + 2)
	    {
	      if (sched_verbose >= 2)
		fprintf (sched_dump,
			 ";;\t\tmodulo scheduled succeeded at II %d\n",
			 modulo_ii);
	      success = true;
	      goto end_schedule;
	    }
	}
      else if (modulo_ii > 0)
	{
	  int stage = clock_var / modulo_ii;
	  if (stage > modulo_max_stages)
	    {
	      if (sched_verbose >= 2)
		fprintf (sched_dump,
			 ";;\t\tfailing schedule due to excessive stages\n");
	      goto end_schedule;
	    }
	  if (modulo_n_insns == modulo_insns_scheduled
	      && stage > modulo_last_stage)
	    {
	      if (sched_verbose >= 2)
		fprintf (sched_dump,
			 ";;\t\tfound kernel after %d stages, II %d\n",
			 stage, modulo_ii);
	      ls.modulo_epilogue = true;
	    }
	}

      prune_ready_list (temp_state, true, false, ls.modulo_epilogue);
      if (ready.n_ready == 0)
	continue;
      if (must_backtrack)
	goto do_backtrack;

      ls.shadows_only_p = false;
      cycle_issued_insns = 0;
      ls.can_issue_more = issue_rate;
      for (;;)
	{
	  rtx_insn *insn;
	  int cost;
	  bool asm_p;

	  if (sort_p && ready.n_ready > 0)
	    {
	      /* Sort the ready list based on priority.  This must be
		 done every iteration through the loop, as schedule_insn
		 may have readied additional insns that will not be
		 sorted correctly.  */
	      ready_sort (&ready);

	      if (sched_verbose >= 2)
		{
		  fprintf (sched_dump,
			   ";;\t\tReady list after ready_sort:    ");
		  debug_ready_list (&ready);
		}
	    }

	  /* We don't want md sched reorder to even see debug isns, so put
	     them out right away.  */
	  if (ready.n_ready && DEBUG_INSN_P (ready_element (&ready, 0))
	      && (*current_sched_info->schedule_more_p) ())
	    {
	      while (ready.n_ready && DEBUG_INSN_P (ready_element (&ready, 0)))
		{
		  rtx_insn *insn = ready_remove_first (&ready);
		  gcc_assert (DEBUG_INSN_P (insn));
		  (*current_sched_info->begin_schedule_ready) (insn);
		  scheduled_insns.safe_push (insn);
		  last_scheduled_insn = insn;
		  advance = schedule_insn (insn);
		  gcc_assert (advance == 0);
		  if (ready.n_ready > 0)
		    ready_sort (&ready);
		}
	    }

	  if (ls.first_cycle_insn_p && !ready.n_ready)
	    break;

	resume_after_backtrack:
	  /* Allow the target to reorder the list, typically for
	     better instruction bundling.  */
	  if (sort_p
	      && (ready.n_ready == 0
		  || !SCHED_GROUP_P (ready_element (&ready, 0))))
	    {
	      if (ls.first_cycle_insn_p && targetm.sched.reorder)
		ls.can_issue_more
		  = targetm.sched.reorder (sched_dump, sched_verbose,
					   ready_lastpos (&ready),
					   &ready.n_ready, clock_var);
	      else if (!ls.first_cycle_insn_p && targetm.sched.reorder2)
		ls.can_issue_more
		  = targetm.sched.reorder2 (sched_dump, sched_verbose,
					    ready.n_ready
					    ? ready_lastpos (&ready) : NULL,
					    &ready.n_ready, clock_var);
	    }

	restart_choose_ready:
	  if (sched_verbose >= 2)
	    {
	      fprintf (sched_dump, ";;\tReady list (t = %3d):  ",
		       clock_var);
	      debug_ready_list (&ready);
	      if (sched_pressure == SCHED_PRESSURE_WEIGHTED)
		print_curr_reg_pressure ();
	    }

	  if (ready.n_ready == 0
	      && ls.can_issue_more
	      && reload_completed)
	    {
	      /* Allow scheduling insns directly from the queue in case
		 there's nothing better to do (ready list is empty) but
		 there are still vacant dispatch slots in the current cycle.  */
	      if (sched_verbose >= 6)
		fprintf (sched_dump,";;\t\tSecond chance\n");
	      memcpy (temp_state, curr_state, dfa_state_size);
	      if (early_queue_to_ready (temp_state, &ready))
		ready_sort (&ready);
	    }

	  if (ready.n_ready == 0
	      || !ls.can_issue_more
	      || state_dead_lock_p (curr_state)
	      || !(*current_sched_info->schedule_more_p) ())
	    break;

	  /* Select and remove the insn from the ready list.  */
	  if (sort_p)
	    {
	      int res;

	      insn = NULL;
	      res = choose_ready (&ready, ls.first_cycle_insn_p, &insn);

	      if (res < 0)
		/* Finish cycle.  */
		break;
	      if (res > 0)
		goto restart_choose_ready;

	      gcc_assert (insn != NULL_RTX);
	    }
	  else
	    insn = ready_remove_first (&ready);

	  if (sched_pressure != SCHED_PRESSURE_NONE
	      && INSN_TICK (insn) > clock_var)
	    {
	      ready_add (&ready, insn, true);
	      advance = 1;
	      break;
	    }

	  if (targetm.sched.dfa_new_cycle
	      && targetm.sched.dfa_new_cycle (sched_dump, sched_verbose,
					      insn, last_clock_var,
					      clock_var, &sort_p))
	    /* SORT_P is used by the target to override sorting
	       of the ready list.  This is needed when the target
	       has modified its internal structures expecting that
	       the insn will be issued next.  As we need the insn
	       to have the highest priority (so it will be returned by
	       the ready_remove_first call above), we invoke
	       ready_add (&ready, insn, true).
	       But, still, there is one issue: INSN can be later
	       discarded by scheduler's front end through
	       current_sched_info->can_schedule_ready_p, hence, won't
	       be issued next.  */
	    {
	      ready_add (&ready, insn, true);
              break;
	    }

	  sort_p = TRUE;

	  if (current_sched_info->can_schedule_ready_p
	      && ! (*current_sched_info->can_schedule_ready_p) (insn))
	    /* We normally get here only if we don't want to move
	       insn from the split block.  */
	    {
	      TODO_SPEC (insn) = DEP_POSTPONED;
	      goto restart_choose_ready;
	    }

	  if (delay_htab)
	    {
	      /* If this insn is the first part of a delay-slot pair, record a
		 backtrack point.  */
	      struct delay_pair *delay_entry;
	      delay_entry
		= delay_htab->find_with_hash (insn, htab_hash_pointer (insn));
	      if (delay_entry)
		{
		  save_backtrack_point (delay_entry, ls);
		  if (sched_verbose >= 2)
		    fprintf (sched_dump, ";;\t\tsaving backtrack point\n");
		}
	    }

	  /* DECISION is made.  */

	  if (modulo_ii > 0 && INSN_UID (insn) < modulo_iter0_max_uid)
	    {
	      modulo_insns_scheduled++;
	      modulo_last_stage = clock_var / modulo_ii;
	    }
          if (TODO_SPEC (insn) & SPECULATIVE)
            generate_recovery_code (insn);

	  if (targetm.sched.dispatch (NULL, IS_DISPATCH_ON))
	    targetm.sched.dispatch_do (insn, ADD_TO_DISPATCH_WINDOW);

	  /* Update counters, etc in the scheduler's front end.  */
	  (*current_sched_info->begin_schedule_ready) (insn);
	  scheduled_insns.safe_push (insn);
	  gcc_assert (NONDEBUG_INSN_P (insn));
	  last_nondebug_scheduled_insn = last_scheduled_insn = insn;

	  if (recog_memoized (insn) >= 0)
	    {
	      memcpy (temp_state, curr_state, dfa_state_size);
	      cost = state_transition (curr_state, insn);
	      if (sched_pressure != SCHED_PRESSURE_WEIGHTED && !sched_fusion)
		gcc_assert (cost < 0);
	      if (memcmp (temp_state, curr_state, dfa_state_size) != 0)
		cycle_issued_insns++;
	      asm_p = false;
	    }
	  else
	    asm_p = (GET_CODE (PATTERN (insn)) == ASM_INPUT
		     || asm_noperands (PATTERN (insn)) >= 0);

	  if (targetm.sched.variable_issue)
	    ls.can_issue_more =
	      targetm.sched.variable_issue (sched_dump, sched_verbose,
					    insn, ls.can_issue_more);
	  /* A naked CLOBBER or USE generates no instruction, so do
	     not count them against the issue rate.  */
	  else if (GET_CODE (PATTERN (insn)) != USE
		   && GET_CODE (PATTERN (insn)) != CLOBBER)
	    ls.can_issue_more--;
	  advance = schedule_insn (insn);

	  if (SHADOW_P (insn))
	    ls.shadows_only_p = true;

	  /* After issuing an asm insn we should start a new cycle.  */
	  if (advance == 0 && asm_p)
	    advance = 1;

	  if (must_backtrack)
	    break;

	  if (advance != 0)
	    break;

	  ls.first_cycle_insn_p = false;
	  if (ready.n_ready > 0)
	    prune_ready_list (temp_state, false, ls.shadows_only_p,
			      ls.modulo_epilogue);
	}

    do_backtrack:
      if (!must_backtrack)
	for (i = 0; i < ready.n_ready; i++)
	  {
	    rtx_insn *insn = ready_element (&ready, i);
	    if (INSN_EXACT_TICK (insn) == clock_var)
	      {
		must_backtrack = true;
		clock_var++;
		break;
	      }
	  }
      if (must_backtrack && modulo_ii > 0)
	{
	  if (modulo_backtracks_left == 0)
	    goto end_schedule;
	  modulo_backtracks_left--;
	}
      while (must_backtrack)
	{
	  struct haifa_saved_data *failed;
	  rtx_insn *failed_insn;

	  must_backtrack = false;
	  failed = verify_shadows ();
	  gcc_assert (failed);

	  failed_insn = failed->delay_pair->i1;
	  /* Clear these queues.  */
	  perform_replacements_new_cycle ();
	  toggle_cancelled_flags (false);
	  unschedule_insns_until (failed_insn);
	  while (failed != backtrack_queue)
	    free_topmost_backtrack_point (true);
	  restore_last_backtrack_point (&ls);
	  if (sched_verbose >= 2)
	    fprintf (sched_dump, ";;\t\trewind to cycle %d\n", clock_var);
	  /* Delay by at least a cycle.  This could cause additional
	     backtracking.  */
	  queue_insn (failed_insn, 1, "backtracked");
	  advance = 0;
	  if (must_backtrack)
	    continue;
	  if (ready.n_ready > 0)
	    goto resume_after_backtrack;
	  else
	    {
	      if (clock_var == 0 && ls.first_cycle_insn_p)
		goto end_schedule;
	      advance = 1;
	      break;
	    }
	}
      ls.first_cycle_insn_p = true;
    }
  if (ls.modulo_epilogue)
    success = true;
 end_schedule:
  if (!ls.first_cycle_insn_p || advance)
    advance_one_cycle ();
  perform_replacements_new_cycle ();
  if (modulo_ii > 0)
    {
      /* Once again, debug insn suckiness: they can be on the ready list
	 even if they have unresolved dependencies.  To make our view
	 of the world consistent, remove such "ready" insns.  */
    restart_debug_insn_loop:
      for (i = ready.n_ready - 1; i >= 0; i--)
	{
	  rtx_insn *x;

	  x = ready_element (&ready, i);
	  if (DEPS_LIST_FIRST (INSN_HARD_BACK_DEPS (x)) != NULL
	      || DEPS_LIST_FIRST (INSN_SPEC_BACK_DEPS (x)) != NULL)
	    {
	      ready_remove (&ready, i);
	      goto restart_debug_insn_loop;
	    }
	}
      for (i = ready.n_ready - 1; i >= 0; i--)
	{
	  rtx_insn *x;

	  x = ready_element (&ready, i);
	  resolve_dependencies (x);
	}
      for (i = 0; i <= max_insn_queue_index; i++)
	{
	  rtx_insn_list *link;
	  while ((link = insn_queue[i]) != NULL)
	    {
	      rtx_insn *x = link->insn ();
	      insn_queue[i] = link->next ();
	      QUEUE_INDEX (x) = QUEUE_NOWHERE;
	      free_INSN_LIST_node (link);
	      resolve_dependencies (x);
	    }
	}
    }

  if (!success)
    undo_all_replacements ();

  /* Debug info.  */
  if (sched_verbose)
    {
      fprintf (sched_dump, ";;\tReady list (final):  ");
      debug_ready_list (&ready);
    }

  if (modulo_ii == 0 && current_sched_info->queue_must_finish_empty)
    /* Sanity check -- queue must be empty now.  Meaningless if region has
       multiple bbs.  */
    gcc_assert (!q_size && !ready.n_ready && !ready.n_debug);
  else if (modulo_ii == 0)
    {
      /* We must maintain QUEUE_INDEX between blocks in region.  */
      for (i = ready.n_ready - 1; i >= 0; i--)
	{
	  rtx_insn *x;

	  x = ready_element (&ready, i);
	  QUEUE_INDEX (x) = QUEUE_NOWHERE;
	  TODO_SPEC (x) = HARD_DEP;
	}

      if (q_size)
	for (i = 0; i <= max_insn_queue_index; i++)
	  {
	    rtx_insn_list *link;
	    for (link = insn_queue[i]; link; link = link->next ())
	      {
		rtx_insn *x;

		x = link->insn ();
		QUEUE_INDEX (x) = QUEUE_NOWHERE;
		TODO_SPEC (x) = HARD_DEP;
	      }
	    free_INSN_LIST_list (&insn_queue[i]);
	  }
    }

  if (sched_pressure == SCHED_PRESSURE_MODEL)
    model_end_schedule ();

  if (success)
    {
      commit_schedule (prev_head, tail, target_bb);
      if (sched_verbose)
	fprintf (sched_dump, ";;   total time = %d\n", clock_var);
    }
  else
    last_scheduled_insn = tail;

  scheduled_insns.truncate (0);

  if (!current_sched_info->queue_must_finish_empty
      || haifa_recovery_bb_recently_added_p)
    {
      /* INSN_TICK (minimum clock tick at which the insn becomes
         ready) may be not correct for the insn in the subsequent
         blocks of the region.  We should use a correct value of
         `clock_var' or modify INSN_TICK.  It is better to keep
         clock_var value equal to 0 at the start of a basic block.
         Therefore we modify INSN_TICK here.  */
      fix_inter_tick (NEXT_INSN (prev_head), last_scheduled_insn);
    }

  if (targetm.sched.finish)
    {
      targetm.sched.finish (sched_dump, sched_verbose);
      /* Target might have added some instructions to the scheduled block
	 in its md_finish () hook.  These new insns don't have any data
	 initialized and to identify them we extend h_i_d so that they'll
	 get zero luids.  */
      sched_extend_luids ();
    }

  /* Update head/tail boundaries.  */
  head = NEXT_INSN (prev_head);
  tail = last_scheduled_insn;

  if (sched_verbose)
    {
      fprintf (sched_dump, ";;   new head = %d\n;;   new tail = %d\n",
	       INSN_UID (head), INSN_UID (tail));

      if (sched_verbose >= 2)
	{
	  dump_insn_stream (head, tail);
	  print_rank_for_schedule_stats (";; TOTAL ", &rank_for_schedule_stats,
					 NULL);
	}

      fprintf (sched_dump, "\n");
    }

  head = restore_other_notes (head, NULL);

  current_sched_info->head = head;
  current_sched_info->tail = tail;

  free_backtrack_queue ();

  return success;
}

/* Set_priorities: compute priority of each insn in the block.  */

int
set_priorities (rtx_insn *head, rtx_insn *tail)
{
  rtx_insn *insn;
  int n_insn;
  int sched_max_insns_priority =
	current_sched_info->sched_max_insns_priority;
  rtx_insn *prev_head;

  if (head == tail && ! INSN_P (head))
    gcc_unreachable ();

  n_insn = 0;

  prev_head = PREV_INSN (head);
  for (insn = tail; insn != prev_head; insn = PREV_INSN (insn))
    {
      if (!INSN_P (insn))
	continue;

      n_insn++;
      (void) priority (insn);

      gcc_assert (INSN_PRIORITY_KNOWN (insn));

      sched_max_insns_priority = MAX (sched_max_insns_priority,
				      INSN_PRIORITY (insn));
    }

  current_sched_info->sched_max_insns_priority = sched_max_insns_priority;

  return n_insn;
}

/* Set sched_dump and sched_verbose for the desired debugging output. */
void
setup_sched_dump (void)
{
  sched_verbose = sched_verbose_param;
  sched_dump = dump_file;
  if (!dump_file)
    sched_verbose = 0;
}

/* Allocate data for register pressure sensitive scheduling.  */
static void
alloc_global_sched_pressure_data (void)
{
  if (sched_pressure != SCHED_PRESSURE_NONE)
    {
      int i, max_regno = max_reg_num ();

      if (sched_dump != NULL)
	/* We need info about pseudos for rtl dumps about pseudo
	   classes and costs.  */
	regstat_init_n_sets_and_refs ();
      ira_set_pseudo_classes (true, sched_verbose ? sched_dump : NULL);
      sched_regno_pressure_class
	= (enum reg_class *) xmalloc (max_regno * sizeof (enum reg_class));
      for (i = 0; i < max_regno; i++)
	sched_regno_pressure_class[i]
	  = (i < FIRST_PSEUDO_REGISTER
	     ? ira_pressure_class_translate[REGNO_REG_CLASS (i)]
	     : ira_pressure_class_translate[reg_allocno_class (i)]);
      curr_reg_live = BITMAP_ALLOC (NULL);
      if (sched_pressure == SCHED_PRESSURE_WEIGHTED)
	{
	  saved_reg_live = BITMAP_ALLOC (NULL);
	  region_ref_regs = BITMAP_ALLOC (NULL);
	}
      if (sched_pressure == SCHED_PRESSURE_MODEL)
	tmp_bitmap = BITMAP_ALLOC (NULL);

      /* Calculate number of CALL_SAVED_REGS and FIXED_REGS in register classes
	 that we calculate register pressure for.  */
      for (int c = 0; c < ira_pressure_classes_num; ++c)
	{
	  enum reg_class cl = ira_pressure_classes[c];

	  call_saved_regs_num[cl] = 0;
	  fixed_regs_num[cl] = 0;

	  for (int i = 0; i < ira_class_hard_regs_num[cl]; ++i)
	    {
	      unsigned int regno = ira_class_hard_regs[cl][i];
	      if (fixed_regs[regno])
		++fixed_regs_num[cl];
	      else if (!crtl->abi->clobbers_full_reg_p (regno))
		++call_saved_regs_num[cl];
	    }
	}
    }
}

/*  Free data for register pressure sensitive scheduling.  Also called
    from schedule_region when stopping sched-pressure early.  */
void
free_global_sched_pressure_data (void)
{
  if (sched_pressure != SCHED_PRESSURE_NONE)
    {
      if (regstat_n_sets_and_refs != NULL)
	regstat_free_n_sets_and_refs ();
      if (sched_pressure == SCHED_PRESSURE_WEIGHTED)
	{
	  BITMAP_FREE (region_ref_regs);
	  BITMAP_FREE (saved_reg_live);
	}
      if (sched_pressure == SCHED_PRESSURE_MODEL)
	BITMAP_FREE (tmp_bitmap);
      BITMAP_FREE (curr_reg_live);
      free (sched_regno_pressure_class);
    }
}

/* Initialize some global state for the scheduler.  This function works
   with the common data shared between all the schedulers.  It is called
   from the scheduler specific initialization routine.  */

void
sched_init (void)
{
  /* Disable speculative loads in their presence if cc0 defined.  */
  if (HAVE_cc0)
  flag_schedule_speculative_load = 0;

  if (targetm.sched.dispatch (NULL, IS_DISPATCH_ON))
    targetm.sched.dispatch_do (NULL, DISPATCH_INIT);

  if (live_range_shrinkage_p)
    sched_pressure = SCHED_PRESSURE_WEIGHTED;
  else if (flag_sched_pressure
	   && !reload_completed
	   && common_sched_info->sched_pass_id == SCHED_RGN_PASS)
    sched_pressure = ((enum sched_pressure_algorithm)
		      param_sched_pressure_algorithm);
  else
    sched_pressure = SCHED_PRESSURE_NONE;

  if (sched_pressure != SCHED_PRESSURE_NONE)
    ira_setup_eliminable_regset ();

  /* Initialize SPEC_INFO.  */
  if (targetm.sched.set_sched_flags)
    {
      spec_info = &spec_info_var;
      targetm.sched.set_sched_flags (spec_info);

      if (spec_info->mask != 0)
        {
	  spec_info->data_weakness_cutoff
	    = (param_sched_spec_prob_cutoff * MAX_DEP_WEAK) / 100;
	  spec_info->control_weakness_cutoff
	    = (param_sched_spec_prob_cutoff * REG_BR_PROB_BASE) / 100;
        }
      else
	/* So we won't read anything accidentally.  */
	spec_info = NULL;

    }
  else
    /* So we won't read anything accidentally.  */
    spec_info = 0;

  /* Initialize issue_rate.  */
  if (targetm.sched.issue_rate)
    issue_rate = targetm.sched.issue_rate ();
  else
    issue_rate = 1;

  if (targetm.sched.first_cycle_multipass_dfa_lookahead
      /* Don't use max_issue with reg_pressure scheduling.  Multipass
	 scheduling and reg_pressure scheduling undo each other's decisions.  */
      && sched_pressure == SCHED_PRESSURE_NONE)
    dfa_lookahead = targetm.sched.first_cycle_multipass_dfa_lookahead ();
  else
    dfa_lookahead = 0;

  /* Set to "0" so that we recalculate.  */
  max_lookahead_tries = 0;

  if (targetm.sched.init_dfa_pre_cycle_insn)
    targetm.sched.init_dfa_pre_cycle_insn ();

  if (targetm.sched.init_dfa_post_cycle_insn)
    targetm.sched.init_dfa_post_cycle_insn ();

  dfa_start ();
  dfa_state_size = state_size ();

  init_alias_analysis ();

  if (!sched_no_dce)
    df_set_flags (DF_LR_RUN_DCE);
  df_note_add_problem ();

  /* More problems needed for interloop dep calculation in SMS.  */
  if (common_sched_info->sched_pass_id == SCHED_SMS_PASS)
    {
      df_rd_add_problem ();
      df_chain_add_problem (DF_DU_CHAIN + DF_UD_CHAIN);
    }

  df_analyze ();

  /* Do not run DCE after reload, as this can kill nops inserted
     by bundling.  */
  if (reload_completed)
    df_clear_flags (DF_LR_RUN_DCE);

  regstat_compute_calls_crossed ();

  if (targetm.sched.init_global)
    targetm.sched.init_global (sched_dump, sched_verbose, get_max_uid () + 1);

  alloc_global_sched_pressure_data ();

  curr_state = xmalloc (dfa_state_size);
}

static void haifa_init_only_bb (basic_block, basic_block);

/* Initialize data structures specific to the Haifa scheduler.  */
void
haifa_sched_init (void)
{
  setup_sched_dump ();
  sched_init ();

  scheduled_insns.create (0);

  if (spec_info != NULL)
    {
      sched_deps_info->use_deps_list = 1;
      sched_deps_info->generate_spec_deps = 1;
    }

  /* Initialize luids, dependency caches, target and h_i_d for the
     whole function.  */
  {
    sched_init_bbs ();

    auto_vec<basic_block> bbs (n_basic_blocks_for_fn (cfun));
    basic_block bb;
    FOR_EACH_BB_FN (bb, cfun)
      bbs.quick_push (bb);
    sched_init_luids (bbs);
    sched_deps_init (true);
    sched_extend_target ();
    haifa_init_h_i_d (bbs);
  }

  sched_init_only_bb = haifa_init_only_bb;
  sched_split_block = sched_split_block_1;
  sched_create_empty_bb = sched_create_empty_bb_1;
  haifa_recovery_bb_ever_added_p = false;

  nr_begin_data = nr_begin_control = nr_be_in_data = nr_be_in_control = 0;
  before_recovery = 0;
  after_recovery = 0;

  modulo_ii = 0;
}

/* Finish work with the data specific to the Haifa scheduler.  */
void
haifa_sched_finish (void)
{
  sched_create_empty_bb = NULL;
  sched_split_block = NULL;
  sched_init_only_bb = NULL;

  if (spec_info && spec_info->dump)
    {
      char c = reload_completed ? 'a' : 'b';

      fprintf (spec_info->dump,
	       ";; %s:\n", current_function_name ());

      fprintf (spec_info->dump,
               ";; Procedure %cr-begin-data-spec motions == %d\n",
               c, nr_begin_data);
      fprintf (spec_info->dump,
               ";; Procedure %cr-be-in-data-spec motions == %d\n",
               c, nr_be_in_data);
      fprintf (spec_info->dump,
               ";; Procedure %cr-begin-control-spec motions == %d\n",
               c, nr_begin_control);
      fprintf (spec_info->dump,
               ";; Procedure %cr-be-in-control-spec motions == %d\n",
               c, nr_be_in_control);
    }

  scheduled_insns.release ();

  /* Finalize h_i_d, dependency caches, and luids for the whole
     function.  Target will be finalized in md_global_finish ().  */
  sched_deps_finish ();
  sched_finish_luids ();
  current_sched_info = NULL;
  insn_queue = NULL;
  sched_finish ();
}

/* Free global data used during insn scheduling.  This function works with
   the common data shared between the schedulers.  */

void
sched_finish (void)
{
  haifa_finish_h_i_d ();
  free_global_sched_pressure_data ();
  free (curr_state);

  if (targetm.sched.finish_global)
    targetm.sched.finish_global (sched_dump, sched_verbose);

  end_alias_analysis ();

  regstat_free_calls_crossed ();

  dfa_finish ();
}

/* Free all delay_pair structures that were recorded.  */
void
free_delay_pairs (void)
{
  if (delay_htab)
    {
      delay_htab->empty ();
      delay_htab_i2->empty ();
    }
}

/* Fix INSN_TICKs of the instructions in the current block as well as
   INSN_TICKs of their dependents.
   HEAD and TAIL are the begin and the end of the current scheduled block.  */
static void
fix_inter_tick (rtx_insn *head, rtx_insn *tail)
{
  /* Set of instructions with corrected INSN_TICK.  */
  auto_bitmap processed;
  /* ??? It is doubtful if we should assume that cycle advance happens on
     basic block boundaries.  Basically insns that are unconditionally ready
     on the start of the block are more preferable then those which have
     a one cycle dependency over insn from the previous block.  */
  int next_clock = clock_var + 1;

  /* Iterates over scheduled instructions and fix their INSN_TICKs and
     INSN_TICKs of dependent instructions, so that INSN_TICKs are consistent
     across different blocks.  */
  for (tail = NEXT_INSN (tail); head != tail; head = NEXT_INSN (head))
    {
      if (INSN_P (head))
	{
	  int tick;
	  sd_iterator_def sd_it;
	  dep_t dep;

	  tick = INSN_TICK (head);
	  gcc_assert (tick >= MIN_TICK);

	  /* Fix INSN_TICK of instruction from just scheduled block.  */
	  if (bitmap_set_bit (processed, INSN_LUID (head)))
	    {
	      tick -= next_clock;

	      if (tick < MIN_TICK)
		tick = MIN_TICK;

	      INSN_TICK (head) = tick;
	    }

	  if (DEBUG_INSN_P (head))
	    continue;

	  FOR_EACH_DEP (head, SD_LIST_RES_FORW, sd_it, dep)
	    {
	      rtx_insn *next;

	      next = DEP_CON (dep);
	      tick = INSN_TICK (next);

	      if (tick != INVALID_TICK
		  /* If NEXT has its INSN_TICK calculated, fix it.
		     If not - it will be properly calculated from
		     scratch later in fix_tick_ready.  */
		  && bitmap_set_bit (processed, INSN_LUID (next)))
		{
		  tick -= next_clock;

		  if (tick < MIN_TICK)
		    tick = MIN_TICK;

		  if (tick > INTER_TICK (next))
		    INTER_TICK (next) = tick;
		  else
		    tick = INTER_TICK (next);

		  INSN_TICK (next) = tick;
		}
	    }
	}
    }
}

/* Check if NEXT is ready to be added to the ready or queue list.
   If "yes", add it to the proper list.
   Returns:
      -1 - is not ready yet,
       0 - added to the ready list,
   0 < N - queued for N cycles.  */
int
try_ready (rtx_insn *next)
{
  ds_t old_ts, new_ts;

  old_ts = TODO_SPEC (next);

  gcc_assert (!(old_ts & ~(SPECULATIVE | HARD_DEP | DEP_CONTROL | DEP_POSTPONED))
	      && (old_ts == HARD_DEP
		  || old_ts == DEP_POSTPONED
		  || (old_ts & SPECULATIVE)
		  || old_ts == DEP_CONTROL));

  new_ts = recompute_todo_spec (next, false);

  if (new_ts & (HARD_DEP | DEP_POSTPONED))
    gcc_assert (new_ts == old_ts
		&& QUEUE_INDEX (next) == QUEUE_NOWHERE);
  else if (current_sched_info->new_ready)
    new_ts = current_sched_info->new_ready (next, new_ts);

  /* * if !(old_ts & SPECULATIVE) (e.g. HARD_DEP or 0), then insn might
     have its original pattern or changed (speculative) one.  This is due
     to changing ebb in region scheduling.
     * But if (old_ts & SPECULATIVE), then we are pretty sure that insn
     has speculative pattern.

     We can't assert (!(new_ts & HARD_DEP) || new_ts == old_ts) here because
     control-speculative NEXT could have been discarded by sched-rgn.c
     (the same case as when discarded by can_schedule_ready_p ()).  */

  if ((new_ts & SPECULATIVE)
      /* If (old_ts == new_ts), then (old_ts & SPECULATIVE) and we don't
	 need to change anything.  */
      && new_ts != old_ts)
    {
      int res;
      rtx new_pat;

      gcc_assert ((new_ts & SPECULATIVE) && !(new_ts & ~SPECULATIVE));

      res = haifa_speculate_insn (next, new_ts, &new_pat);

      switch (res)
	{
	case -1:
	  /* It would be nice to change DEP_STATUS of all dependences,
	     which have ((DEP_STATUS & SPECULATIVE) == new_ts) to HARD_DEP,
	     so we won't reanalyze anything.  */
	  new_ts = HARD_DEP;
	  break;

	case 0:
	  /* We follow the rule, that every speculative insn
	     has non-null ORIG_PAT.  */
	  if (!ORIG_PAT (next))
	    ORIG_PAT (next) = PATTERN (next);
	  break;

	case 1:
	  if (!ORIG_PAT (next))
	    /* If we gonna to overwrite the original pattern of insn,
	       save it.  */
	    ORIG_PAT (next) = PATTERN (next);

	  res = haifa_change_pattern (next, new_pat);
	  gcc_assert (res);
	  break;

	default:
	  gcc_unreachable ();
	}
    }

  /* We need to restore pattern only if (new_ts == 0), because otherwise it is
     either correct (new_ts & SPECULATIVE),
     or we simply don't care (new_ts & HARD_DEP).  */

  gcc_assert (!ORIG_PAT (next)
	      || !IS_SPECULATION_BRANCHY_CHECK_P (next));

  TODO_SPEC (next) = new_ts;

  if (new_ts & (HARD_DEP | DEP_POSTPONED))
    {
      /* We can't assert (QUEUE_INDEX (next) == QUEUE_NOWHERE) here because
	 control-speculative NEXT could have been discarded by sched-rgn.c
	 (the same case as when discarded by can_schedule_ready_p ()).  */
      /*gcc_assert (QUEUE_INDEX (next) == QUEUE_NOWHERE);*/

      change_queue_index (next, QUEUE_NOWHERE);

      return -1;
    }
  else if (!(new_ts & BEGIN_SPEC)
	   && ORIG_PAT (next) && PREDICATED_PAT (next) == NULL_RTX
	   && !IS_SPECULATION_CHECK_P (next))
    /* We should change pattern of every previously speculative
       instruction - and we determine if NEXT was speculative by using
       ORIG_PAT field.  Except one case - speculation checks have ORIG_PAT
       pat too, so skip them.  */
    {
      bool success = haifa_change_pattern (next, ORIG_PAT (next));
      gcc_assert (success);
      ORIG_PAT (next) = 0;
    }

  if (sched_verbose >= 2)
    {
      fprintf (sched_dump, ";;\t\tdependencies resolved: insn %s",
               (*current_sched_info->print_insn) (next, 0));

      if (spec_info && spec_info->dump)
        {
          if (new_ts & BEGIN_DATA)
            fprintf (spec_info->dump, "; data-spec;");
          if (new_ts & BEGIN_CONTROL)
            fprintf (spec_info->dump, "; control-spec;");
          if (new_ts & BE_IN_CONTROL)
            fprintf (spec_info->dump, "; in-control-spec;");
        }
      if (TODO_SPEC (next) & DEP_CONTROL)
	fprintf (sched_dump, " predicated");
      fprintf (sched_dump, "\n");
    }

  adjust_priority (next);

  return fix_tick_ready (next);
}

/* Calculate INSN_TICK of NEXT and add it to either ready or queue list.  */
static int
fix_tick_ready (rtx_insn *next)
{
  int tick, delay;

  if (!DEBUG_INSN_P (next) && !sd_lists_empty_p (next, SD_LIST_RES_BACK))
    {
      int full_p;
      sd_iterator_def sd_it;
      dep_t dep;

      tick = INSN_TICK (next);
      /* if tick is not equal to INVALID_TICK, then update
	 INSN_TICK of NEXT with the most recent resolved dependence
	 cost.  Otherwise, recalculate from scratch.  */
      full_p = (tick == INVALID_TICK);

      FOR_EACH_DEP (next, SD_LIST_RES_BACK, sd_it, dep)
        {
          rtx_insn *pro = DEP_PRO (dep);
          int tick1;

	  gcc_assert (INSN_TICK (pro) >= MIN_TICK);

          tick1 = INSN_TICK (pro) + dep_cost (dep);
          if (tick1 > tick)
            tick = tick1;

	  if (!full_p)
	    break;
        }
    }
  else
    tick = -1;

  INSN_TICK (next) = tick;

  delay = tick - clock_var;
  if (delay <= 0 || sched_pressure != SCHED_PRESSURE_NONE || sched_fusion)
    delay = QUEUE_READY;

  change_queue_index (next, delay);

  return delay;
}

/* Move NEXT to the proper queue list with (DELAY >= 1),
   or add it to the ready list (DELAY == QUEUE_READY),
   or remove it from ready and queue lists at all (DELAY == QUEUE_NOWHERE).  */
static void
change_queue_index (rtx_insn *next, int delay)
{
  int i = QUEUE_INDEX (next);

  gcc_assert (QUEUE_NOWHERE <= delay && delay <= max_insn_queue_index
	      && delay != 0);
  gcc_assert (i != QUEUE_SCHEDULED);

  if ((delay > 0 && NEXT_Q_AFTER (q_ptr, delay) == i)
      || (delay < 0 && delay == i))
    /* We have nothing to do.  */
    return;

  /* Remove NEXT from wherever it is now.  */
  if (i == QUEUE_READY)
    ready_remove_insn (next);
  else if (i >= 0)
    queue_remove (next);

  /* Add it to the proper place.  */
  if (delay == QUEUE_READY)
    ready_add (readyp, next, false);
  else if (delay >= 1)
    queue_insn (next, delay, "change queue index");

  if (sched_verbose >= 2)
    {
      fprintf (sched_dump, ";;\t\ttick updated: insn %s",
	       (*current_sched_info->print_insn) (next, 0));

      if (delay == QUEUE_READY)
	fprintf (sched_dump, " into ready\n");
      else if (delay >= 1)
	fprintf (sched_dump, " into queue with cost=%d\n", delay);
      else
	fprintf (sched_dump, " removed from ready or queue lists\n");
    }
}

static int sched_ready_n_insns = -1;

/* Initialize per region data structures.  */
void
sched_extend_ready_list (int new_sched_ready_n_insns)
{
  int i;

  if (sched_ready_n_insns == -1)
    /* At the first call we need to initialize one more choice_stack
       entry.  */
    {
      i = 0;
      sched_ready_n_insns = 0;
      scheduled_insns.reserve (new_sched_ready_n_insns);
    }
  else
    i = sched_ready_n_insns + 1;

  ready.veclen = new_sched_ready_n_insns + issue_rate;
  ready.vec = XRESIZEVEC (rtx_insn *, ready.vec, ready.veclen);

  gcc_assert (new_sched_ready_n_insns >= sched_ready_n_insns);

  ready_try = (signed char *) xrecalloc (ready_try, new_sched_ready_n_insns,
					 sched_ready_n_insns,
					 sizeof (*ready_try));

  /* We allocate +1 element to save initial state in the choice_stack[0]
     entry.  */
  choice_stack = XRESIZEVEC (struct choice_entry, choice_stack,
			     new_sched_ready_n_insns + 1);

  for (; i <= new_sched_ready_n_insns; i++)
    {
      choice_stack[i].state = xmalloc (dfa_state_size);

      if (targetm.sched.first_cycle_multipass_init)
	targetm.sched.first_cycle_multipass_init (&(choice_stack[i]
						    .target_data));
    }

  sched_ready_n_insns = new_sched_ready_n_insns;
}

/* Free per region data structures.  */
void
sched_finish_ready_list (void)
{
  int i;

  free (ready.vec);
  ready.vec = NULL;
  ready.veclen = 0;

  free (ready_try);
  ready_try = NULL;

  for (i = 0; i <= sched_ready_n_insns; i++)
    {
      if (targetm.sched.first_cycle_multipass_fini)
	targetm.sched.first_cycle_multipass_fini (&(choice_stack[i]
						    .target_data));

      free (choice_stack [i].state);
    }
  free (choice_stack);
  choice_stack = NULL;

  sched_ready_n_insns = -1;
}

static int
haifa_luid_for_non_insn (rtx x)
{
  gcc_assert (NOTE_P (x) || LABEL_P (x));

  return 0;
}

/* Generates recovery code for INSN.  */
static void
generate_recovery_code (rtx_insn *insn)
{
  if (TODO_SPEC (insn) & BEGIN_SPEC)
    begin_speculative_block (insn);

  /* Here we have insn with no dependencies to
     instructions other then CHECK_SPEC ones.  */

  if (TODO_SPEC (insn) & BE_IN_SPEC)
    add_to_speculative_block (insn);
}

/* Helper function.
   Tries to add speculative dependencies of type FS between instructions
   in deps_list L and TWIN.  */
static void
process_insn_forw_deps_be_in_spec (rtx_insn *insn, rtx_insn *twin, ds_t fs)
{
  sd_iterator_def sd_it;
  dep_t dep;

  FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
    {
      ds_t ds;
      rtx_insn *consumer;

      consumer = DEP_CON (dep);

      ds = DEP_STATUS (dep);

      if (/* If we want to create speculative dep.  */
	  fs
	  /* And we can do that because this is a true dep.  */
	  && (ds & DEP_TYPES) == DEP_TRUE)
	{
	  gcc_assert (!(ds & BE_IN_SPEC));

	  if (/* If this dep can be overcome with 'begin speculation'.  */
	      ds & BEGIN_SPEC)
	    /* Then we have a choice: keep the dep 'begin speculative'
	       or transform it into 'be in speculative'.  */
	    {
	      if (/* In try_ready we assert that if insn once became ready
		     it can be removed from the ready (or queue) list only
		     due to backend decision.  Hence we can't let the
		     probability of the speculative dep to decrease.  */
		  ds_weak (ds) <= ds_weak (fs))
		{
		  ds_t new_ds;

		  new_ds = (ds & ~BEGIN_SPEC) | fs;

		  if (/* consumer can 'be in speculative'.  */
		      sched_insn_is_legitimate_for_speculation_p (consumer,
								  new_ds))
		    /* Transform it to be in speculative.  */
		    ds = new_ds;
		}
	    }
	  else
	    /* Mark the dep as 'be in speculative'.  */
	    ds |= fs;
	}

      {
	dep_def _new_dep, *new_dep = &_new_dep;

	init_dep_1 (new_dep, twin, consumer, DEP_TYPE (dep), ds);
	sd_add_dep (new_dep, false);
      }
    }
}

/* Generates recovery code for BEGIN speculative INSN.  */
static void
begin_speculative_block (rtx_insn *insn)
{
  if (TODO_SPEC (insn) & BEGIN_DATA)
    nr_begin_data++;
  if (TODO_SPEC (insn) & BEGIN_CONTROL)
    nr_begin_control++;

  create_check_block_twin (insn, false);

  TODO_SPEC (insn) &= ~BEGIN_SPEC;
}

static void haifa_init_insn (rtx_insn *);

/* Generates recovery code for BE_IN speculative INSN.  */
static void
add_to_speculative_block (rtx_insn *insn)
{
  ds_t ts;
  sd_iterator_def sd_it;
  dep_t dep;
  auto_vec<rtx_insn *, 10> twins;

  ts = TODO_SPEC (insn);
  gcc_assert (!(ts & ~BE_IN_SPEC));

  if (ts & BE_IN_DATA)
    nr_be_in_data++;
  if (ts & BE_IN_CONTROL)
    nr_be_in_control++;

  TODO_SPEC (insn) &= ~BE_IN_SPEC;
  gcc_assert (!TODO_SPEC (insn));

  DONE_SPEC (insn) |= ts;

  /* First we convert all simple checks to branchy.  */
  for (sd_it = sd_iterator_start (insn, SD_LIST_SPEC_BACK);
       sd_iterator_cond (&sd_it, &dep);)
    {
      rtx_insn *check = DEP_PRO (dep);

      if (IS_SPECULATION_SIMPLE_CHECK_P (check))
	{
	  create_check_block_twin (check, true);

	  /* Restart search.  */
	  sd_it = sd_iterator_start (insn, SD_LIST_SPEC_BACK);
	}
      else
	/* Continue search.  */
	sd_iterator_next (&sd_it);
    }

  auto_vec<rtx_insn *> priorities_roots;
  clear_priorities (insn, &priorities_roots);

  while (1)
    {
      rtx_insn *check, *twin;
      basic_block rec;

      /* Get the first backward dependency of INSN.  */
      sd_it = sd_iterator_start (insn, SD_LIST_SPEC_BACK);
      if (!sd_iterator_cond (&sd_it, &dep))
	/* INSN has no backward dependencies left.  */
	break;

      gcc_assert ((DEP_STATUS (dep) & BEGIN_SPEC) == 0
		  && (DEP_STATUS (dep) & BE_IN_SPEC) != 0
		  && (DEP_STATUS (dep) & DEP_TYPES) == DEP_TRUE);

      check = DEP_PRO (dep);

      gcc_assert (!IS_SPECULATION_CHECK_P (check) && !ORIG_PAT (check)
		  && QUEUE_INDEX (check) == QUEUE_NOWHERE);

      rec = BLOCK_FOR_INSN (check);

      twin = emit_insn_before (copy_insn (PATTERN (insn)), BB_END (rec));
      haifa_init_insn (twin);

      sd_copy_back_deps (twin, insn, true);

      if (sched_verbose && spec_info->dump)
        /* INSN_BB (insn) isn't determined for twin insns yet.
           So we can't use current_sched_info->print_insn.  */
        fprintf (spec_info->dump, ";;\t\tGenerated twin insn : %d/rec%d\n",
                 INSN_UID (twin), rec->index);

      twins.safe_push (twin);

      /* Add dependences between TWIN and all appropriate
	 instructions from REC.  */
      FOR_EACH_DEP (insn, SD_LIST_SPEC_BACK, sd_it, dep)
	{
	  rtx_insn *pro = DEP_PRO (dep);

	  gcc_assert (DEP_TYPE (dep) == REG_DEP_TRUE);

	  /* INSN might have dependencies from the instructions from
	     several recovery blocks.  At this iteration we process those
	     producers that reside in REC.  */
	  if (BLOCK_FOR_INSN (pro) == rec)
	    {
	      dep_def _new_dep, *new_dep = &_new_dep;

	      init_dep (new_dep, pro, twin, REG_DEP_TRUE);
	      sd_add_dep (new_dep, false);
	    }
	}

      process_insn_forw_deps_be_in_spec (insn, twin, ts);

      /* Remove all dependencies between INSN and insns in REC.  */
      for (sd_it = sd_iterator_start (insn, SD_LIST_SPEC_BACK);
	   sd_iterator_cond (&sd_it, &dep);)
	{
	  rtx_insn *pro = DEP_PRO (dep);

	  if (BLOCK_FOR_INSN (pro) == rec)
	    sd_delete_dep (sd_it);
	  else
	    sd_iterator_next (&sd_it);
	}
    }

  /* We couldn't have added the dependencies between INSN and TWINS earlier
     because that would make TWINS appear in the INSN_BACK_DEPS (INSN).  */
  unsigned int i;
  rtx_insn *twin;
  FOR_EACH_VEC_ELT_REVERSE (twins, i, twin)
    {
      dep_def _new_dep, *new_dep = &_new_dep;

      init_dep (new_dep, insn, twin, REG_DEP_OUTPUT);
      sd_add_dep (new_dep, false);
    }

  calc_priorities (priorities_roots);
}

/* Extends and fills with zeros (only the new part) array pointed to by P.  */
void *
xrecalloc (void *p, size_t new_nmemb, size_t old_nmemb, size_t size)
{
  gcc_assert (new_nmemb >= old_nmemb);
  p = XRESIZEVAR (void, p, new_nmemb * size);
  memset (((char *) p) + old_nmemb * size, 0, (new_nmemb - old_nmemb) * size);
  return p;
}

/* Helper function.
   Find fallthru edge from PRED.  */
edge
find_fallthru_edge_from (basic_block pred)
{
  edge e;
  basic_block succ;

  succ = pred->next_bb;
  gcc_assert (succ->prev_bb == pred);

  if (EDGE_COUNT (pred->succs) <= EDGE_COUNT (succ->preds))
    {
      e = find_fallthru_edge (pred->succs);

      if (e)
	{
	  gcc_assert (e->dest == succ || e->dest->index == EXIT_BLOCK);
	  return e;
	}
    }
  else
    {
      e = find_fallthru_edge (succ->preds);

      if (e)
	{
	  gcc_assert (e->src == pred);
	  return e;
	}
    }

  return NULL;
}

/* Extend per basic block data structures.  */
static void
sched_extend_bb (void)
{
  /* The following is done to keep current_sched_info->next_tail non null.  */
  rtx_insn *end = BB_END (EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb);
  rtx_insn *insn = DEBUG_INSN_P (end) ? prev_nondebug_insn (end) : end;
  if (NEXT_INSN (end) == 0
      || (!NOTE_P (insn)
	  && !LABEL_P (insn)
	  /* Don't emit a NOTE if it would end up before a BARRIER.  */
	  && !BARRIER_P (next_nondebug_insn (end))))
    {
      rtx_note *note = emit_note_after (NOTE_INSN_DELETED, end);
      /* Make note appear outside BB.  */
      set_block_for_insn (note, NULL);
      BB_END (EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb) = end;
    }
}

/* Init per basic block data structures.  */
void
sched_init_bbs (void)
{
  sched_extend_bb ();
}

/* Initialize BEFORE_RECOVERY variable.  */
static void
init_before_recovery (basic_block *before_recovery_ptr)
{
  basic_block last;
  edge e;

  last = EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb;
  e = find_fallthru_edge_from (last);

  if (e)
    {
      /* We create two basic blocks:
         1. Single instruction block is inserted right after E->SRC
         and has jump to
         2. Empty block right before EXIT_BLOCK.
         Between these two blocks recovery blocks will be emitted.  */

      basic_block single, empty;

      /* If the fallthrough edge to exit we've found is from the block we've
	 created before, don't do anything more.  */
      if (last == after_recovery)
	return;

      adding_bb_to_current_region_p = false;

      single = sched_create_empty_bb (last);
      empty = sched_create_empty_bb (single);

      /* Add new blocks to the root loop.  */
      if (current_loops != NULL)
	{
	  add_bb_to_loop (single, (*current_loops->larray)[0]);
	  add_bb_to_loop (empty, (*current_loops->larray)[0]);
	}

      single->count = last->count;
      empty->count = last->count;
      BB_COPY_PARTITION (single, last);
      BB_COPY_PARTITION (empty, last);

      redirect_edge_succ (e, single);
      make_single_succ_edge (single, empty, 0);
      make_single_succ_edge (empty, EXIT_BLOCK_PTR_FOR_FN (cfun),
			     EDGE_FALLTHRU);

      rtx_code_label *label = block_label (empty);
      rtx_jump_insn *x = emit_jump_insn_after (targetm.gen_jump (label),
					       BB_END (single));
      JUMP_LABEL (x) = label;
      LABEL_NUSES (label)++;
      haifa_init_insn (x);

      emit_barrier_after (x);

      sched_init_only_bb (empty, NULL);
      sched_init_only_bb (single, NULL);
      sched_extend_bb ();

      adding_bb_to_current_region_p = true;
      before_recovery = single;
      after_recovery = empty;

      if (before_recovery_ptr)
        *before_recovery_ptr = before_recovery;

      if (sched_verbose >= 2 && spec_info->dump)
        fprintf (spec_info->dump,
		 ";;\t\tFixed fallthru to EXIT : %d->>%d->%d->>EXIT\n",
                 last->index, single->index, empty->index);
    }
  else
    before_recovery = last;
}

/* Returns new recovery block.  */
basic_block
sched_create_recovery_block (basic_block *before_recovery_ptr)
{
  rtx_insn *barrier;
  basic_block rec;

  haifa_recovery_bb_recently_added_p = true;
  haifa_recovery_bb_ever_added_p = true;

  init_before_recovery (before_recovery_ptr);

  barrier = get_last_bb_insn (before_recovery);
  gcc_assert (BARRIER_P (barrier));

  rtx_insn *label = emit_label_after (gen_label_rtx (), barrier);

  rec = create_basic_block (label, label, before_recovery);

  /* A recovery block always ends with an unconditional jump.  */
  emit_barrier_after (BB_END (rec));

  if (BB_PARTITION (before_recovery) != BB_UNPARTITIONED)
    BB_SET_PARTITION (rec, BB_COLD_PARTITION);

  if (sched_verbose && spec_info->dump)
    fprintf (spec_info->dump, ";;\t\tGenerated recovery block rec%d\n",
             rec->index);

  return rec;
}

/* Create edges: FIRST_BB -> REC; FIRST_BB -> SECOND_BB; REC -> SECOND_BB
   and emit necessary jumps.  */
void
sched_create_recovery_edges (basic_block first_bb, basic_block rec,
			     basic_block second_bb)
{
  int edge_flags;

  /* This is fixing of incoming edge.  */
  /* ??? Which other flags should be specified?  */
  if (BB_PARTITION (first_bb) != BB_PARTITION (rec))
    /* Partition type is the same, if it is "unpartitioned".  */
    edge_flags = EDGE_CROSSING;
  else
    edge_flags = 0;

  edge e2 = single_succ_edge (first_bb);
  edge e = make_edge (first_bb, rec, edge_flags);

  /* TODO: The actual probability can be determined and is computed as
     'todo_spec' variable in create_check_block_twin and
     in sel-sched.c `check_ds' in create_speculation_check.  */
  e->probability = profile_probability::very_unlikely ();
  rec->count = e->count ();
  e2->probability = e->probability.invert ();

  rtx_code_label *label = block_label (second_bb);
  rtx_jump_insn *jump = emit_jump_insn_after (targetm.gen_jump (label),
					      BB_END (rec));
  JUMP_LABEL (jump) = label;
  LABEL_NUSES (label)++;

  if (BB_PARTITION (second_bb) != BB_PARTITION (rec))
    /* Partition type is the same, if it is "unpartitioned".  */
    {
      /* Rewritten from cfgrtl.c.  */
      if (crtl->has_bb_partition && targetm_common.have_named_sections)
	{
	  /* We don't need the same note for the check because
	     any_condjump_p (check) == true.  */
	  CROSSING_JUMP_P (jump) = 1;
	}
      edge_flags = EDGE_CROSSING;
    }
  else
    edge_flags = 0;

  make_single_succ_edge (rec, second_bb, edge_flags);
  if (dom_info_available_p (CDI_DOMINATORS))
    set_immediate_dominator (CDI_DOMINATORS, rec, first_bb);
}

/* This function creates recovery code for INSN.  If MUTATE_P is nonzero,
   INSN is a simple check, that should be converted to branchy one.  */
static void
create_check_block_twin (rtx_insn *insn, bool mutate_p)
{
  basic_block rec;
  rtx_insn *label, *check, *twin;
  rtx check_pat;
  ds_t fs;
  sd_iterator_def sd_it;
  dep_t dep;
  dep_def _new_dep, *new_dep = &_new_dep;
  ds_t todo_spec;

  gcc_assert (ORIG_PAT (insn) != NULL_RTX);

  if (!mutate_p)
    todo_spec = TODO_SPEC (insn);
  else
    {
      gcc_assert (IS_SPECULATION_SIMPLE_CHECK_P (insn)
		  && (TODO_SPEC (insn) & SPECULATIVE) == 0);

      todo_spec = CHECK_SPEC (insn);
    }

  todo_spec &= SPECULATIVE;

  /* Create recovery block.  */
  if (mutate_p || targetm.sched.needs_block_p (todo_spec))
    {
      rec = sched_create_recovery_block (NULL);
      label = BB_HEAD (rec);
    }
  else
    {
      rec = EXIT_BLOCK_PTR_FOR_FN (cfun);
      label = NULL;
    }

  /* Emit CHECK.  */
  check_pat = targetm.sched.gen_spec_check (insn, label, todo_spec);

  if (rec != EXIT_BLOCK_PTR_FOR_FN (cfun))
    {
      /* To have mem_reg alive at the beginning of second_bb,
	 we emit check BEFORE insn, so insn after splitting
	 insn will be at the beginning of second_bb, which will
	 provide us with the correct life information.  */
      check = emit_jump_insn_before (check_pat, insn);
      JUMP_LABEL (check) = label;
      LABEL_NUSES (label)++;
    }
  else
    check = emit_insn_before (check_pat, insn);

  /* Extend data structures.  */
  haifa_init_insn (check);

  /* CHECK is being added to current region.  Extend ready list.  */
  gcc_assert (sched_ready_n_insns != -1);
  sched_extend_ready_list (sched_ready_n_insns + 1);

  if (current_sched_info->add_remove_insn)
    current_sched_info->add_remove_insn (insn, 0);

  RECOVERY_BLOCK (check) = rec;

  if (sched_verbose && spec_info->dump)
    fprintf (spec_info->dump, ";;\t\tGenerated check insn : %s\n",
             (*current_sched_info->print_insn) (check, 0));

  gcc_assert (ORIG_PAT (insn));

  /* Initialize TWIN (twin is a duplicate of original instruction
     in the recovery block).  */
  if (rec != EXIT_BLOCK_PTR_FOR_FN (cfun))
    {
      sd_iterator_def sd_it;
      dep_t dep;

      FOR_EACH_DEP (insn, SD_LIST_RES_BACK, sd_it, dep)
	if ((DEP_STATUS (dep) & DEP_OUTPUT) != 0)
	  {
	    struct _dep _dep2, *dep2 = &_dep2;

	    init_dep (dep2, DEP_PRO (dep), check, REG_DEP_TRUE);

	    sd_add_dep (dep2, true);
	  }

      twin = emit_insn_after (ORIG_PAT (insn), BB_END (rec));
      haifa_init_insn (twin);

      if (sched_verbose && spec_info->dump)
	/* INSN_BB (insn) isn't determined for twin insns yet.
	   So we can't use current_sched_info->print_insn.  */
	fprintf (spec_info->dump, ";;\t\tGenerated twin insn : %d/rec%d\n",
		 INSN_UID (twin), rec->index);
    }
  else
    {
      ORIG_PAT (check) = ORIG_PAT (insn);
      HAS_INTERNAL_DEP (check) = 1;
      twin = check;
      /* ??? We probably should change all OUTPUT dependencies to
	 (TRUE | OUTPUT).  */
    }

  /* Copy all resolved back dependencies of INSN to TWIN.  This will
     provide correct value for INSN_TICK (TWIN).  */
  sd_copy_back_deps (twin, insn, true);

  if (rec != EXIT_BLOCK_PTR_FOR_FN (cfun))
    /* In case of branchy check, fix CFG.  */
    {
      basic_block first_bb, second_bb;
      rtx_insn *jump;

      first_bb = BLOCK_FOR_INSN (check);
      second_bb = sched_split_block (first_bb, check);

      sched_create_recovery_edges (first_bb, rec, second_bb);

      sched_init_only_bb (second_bb, first_bb);
      sched_init_only_bb (rec, EXIT_BLOCK_PTR_FOR_FN (cfun));

      jump = BB_END (rec);
      haifa_init_insn (jump);
    }

  /* Move backward dependences from INSN to CHECK and
     move forward dependences from INSN to TWIN.  */

  /* First, create dependencies between INSN's producers and CHECK & TWIN.  */
  FOR_EACH_DEP (insn, SD_LIST_BACK, sd_it, dep)
    {
      rtx_insn *pro = DEP_PRO (dep);
      ds_t ds;

      /* If BEGIN_DATA: [insn ~~TRUE~~> producer]:
	 check --TRUE--> producer  ??? or ANTI ???
	 twin  --TRUE--> producer
	 twin  --ANTI--> check

	 If BEGIN_CONTROL: [insn ~~ANTI~~> producer]:
	 check --ANTI--> producer
	 twin  --ANTI--> producer
	 twin  --ANTI--> check

	 If BE_IN_SPEC: [insn ~~TRUE~~> producer]:
	 check ~~TRUE~~> producer
	 twin  ~~TRUE~~> producer
	 twin  --ANTI--> check  */

      ds = DEP_STATUS (dep);

      if (ds & BEGIN_SPEC)
	{
	  gcc_assert (!mutate_p);
	  ds &= ~BEGIN_SPEC;
	}

      init_dep_1 (new_dep, pro, check, DEP_TYPE (dep), ds);
      sd_add_dep (new_dep, false);

      if (rec != EXIT_BLOCK_PTR_FOR_FN (cfun))
	{
	  DEP_CON (new_dep) = twin;
	  sd_add_dep (new_dep, false);
	}
    }

  /* Second, remove backward dependencies of INSN.  */
  for (sd_it = sd_iterator_start (insn, SD_LIST_SPEC_BACK);
       sd_iterator_cond (&sd_it, &dep);)
    {
      if ((DEP_STATUS (dep) & BEGIN_SPEC)
	  || mutate_p)
	/* We can delete this dep because we overcome it with
	   BEGIN_SPECULATION.  */
	sd_delete_dep (sd_it);
      else
	sd_iterator_next (&sd_it);
    }

  /* Future Speculations.  Determine what BE_IN speculations will be like.  */
  fs = 0;

  /* Fields (DONE_SPEC (x) & BEGIN_SPEC) and CHECK_SPEC (x) are set only
     here.  */

  gcc_assert (!DONE_SPEC (insn));

  if (!mutate_p)
    {
      ds_t ts = TODO_SPEC (insn);

      DONE_SPEC (insn) = ts & BEGIN_SPEC;
      CHECK_SPEC (check) = ts & BEGIN_SPEC;

      /* Luckiness of future speculations solely depends upon initial
	 BEGIN speculation.  */
      if (ts & BEGIN_DATA)
	fs = set_dep_weak (fs, BE_IN_DATA, get_dep_weak (ts, BEGIN_DATA));
      if (ts & BEGIN_CONTROL)
	fs = set_dep_weak (fs, BE_IN_CONTROL,
			   get_dep_weak (ts, BEGIN_CONTROL));
    }
  else
    CHECK_SPEC (check) = CHECK_SPEC (insn);

  /* Future speculations: call the helper.  */
  process_insn_forw_deps_be_in_spec (insn, twin, fs);

  if (rec != EXIT_BLOCK_PTR_FOR_FN (cfun))
    {
      /* Which types of dependencies should we use here is,
	 generally, machine-dependent question...  But, for now,
	 it is not.  */

      if (!mutate_p)
	{
	  init_dep (new_dep, insn, check, REG_DEP_TRUE);
	  sd_add_dep (new_dep, false);

	  init_dep (new_dep, insn, twin, REG_DEP_OUTPUT);
	  sd_add_dep (new_dep, false);
	}
      else
	{
	  if (spec_info->dump)
	    fprintf (spec_info->dump, ";;\t\tRemoved simple check : %s\n",
		     (*current_sched_info->print_insn) (insn, 0));

	  /* Remove all dependencies of the INSN.  */
	  {
	    sd_it = sd_iterator_start (insn, (SD_LIST_FORW
					      | SD_LIST_BACK
					      | SD_LIST_RES_BACK));
	    while (sd_iterator_cond (&sd_it, &dep))
	      sd_delete_dep (sd_it);
	  }

	  /* If former check (INSN) already was moved to the ready (or queue)
	     list, add new check (CHECK) there too.  */
	  if (QUEUE_INDEX (insn) != QUEUE_NOWHERE)
	    try_ready (check);

	  /* Remove old check from instruction stream and free its
	     data.  */
	  sched_remove_insn (insn);
	}

      init_dep (new_dep, check, twin, REG_DEP_ANTI);
      sd_add_dep (new_dep, false);
    }
  else
    {
      init_dep_1 (new_dep, insn, check, REG_DEP_TRUE, DEP_TRUE | DEP_OUTPUT);
      sd_add_dep (new_dep, false);
    }

  if (!mutate_p)
    /* Fix priorities.  If MUTATE_P is nonzero, this is not necessary,
       because it'll be done later in add_to_speculative_block.  */
    {
      auto_vec<rtx_insn *> priorities_roots;

      clear_priorities (twin, &priorities_roots);
      calc_priorities (priorities_roots);
    }
}

/* Removes dependency between instructions in the recovery block REC
   and usual region instructions.  It keeps inner dependences so it
   won't be necessary to recompute them.  */
static void
fix_recovery_deps (basic_block rec)
{
  rtx_insn *note, *insn, *jump;
  auto_vec<rtx_insn *, 10> ready_list;
  auto_bitmap in_ready;

  /* NOTE - a basic block note.  */
  note = NEXT_INSN (BB_HEAD (rec));
  gcc_assert (NOTE_INSN_BASIC_BLOCK_P (note));
  insn = BB_END (rec);
  gcc_assert (JUMP_P (insn));
  insn = PREV_INSN (insn);

  do
    {
      sd_iterator_def sd_it;
      dep_t dep;

      for (sd_it = sd_iterator_start (insn, SD_LIST_FORW);
	   sd_iterator_cond (&sd_it, &dep);)
	{
	  rtx_insn *consumer = DEP_CON (dep);

	  if (BLOCK_FOR_INSN (consumer) != rec)
	    {
	      sd_delete_dep (sd_it);

	      if (bitmap_set_bit (in_ready, INSN_LUID (consumer)))
		ready_list.safe_push (consumer);
	    }
	  else
	    {
	      gcc_assert ((DEP_STATUS (dep) & DEP_TYPES) == DEP_TRUE);

	      sd_iterator_next (&sd_it);
	    }
	}

      insn = PREV_INSN (insn);
    }
  while (insn != note);

  /* Try to add instructions to the ready or queue list.  */
  unsigned int i;
  rtx_insn *temp;
  FOR_EACH_VEC_ELT_REVERSE (ready_list, i, temp)
    try_ready (temp);

  /* Fixing jump's dependences.  */
  insn = BB_HEAD (rec);
  jump = BB_END (rec);

  gcc_assert (LABEL_P (insn));
  insn = NEXT_INSN (insn);

  gcc_assert (NOTE_INSN_BASIC_BLOCK_P (insn));
  add_jump_dependencies (insn, jump);
}

/* Change pattern of INSN to NEW_PAT.  Invalidate cached haifa
   instruction data.  */
static bool
haifa_change_pattern (rtx_insn *insn, rtx new_pat)
{
  int t;

  t = validate_change (insn, &PATTERN (insn), new_pat, 0);
  if (!t)
    return false;

  update_insn_after_change (insn);
  return true;
}

/* -1 - can't speculate,
   0 - for speculation with REQUEST mode it is OK to use
   current instruction pattern,
   1 - need to change pattern for *NEW_PAT to be speculative.  */
int
sched_speculate_insn (rtx_insn *insn, ds_t request, rtx *new_pat)
{
  gcc_assert (current_sched_info->flags & DO_SPECULATION
              && (request & SPECULATIVE)
	      && sched_insn_is_legitimate_for_speculation_p (insn, request));

  if ((request & spec_info->mask) != request)
    return -1;

  if (request & BE_IN_SPEC
      && !(request & BEGIN_SPEC))
    return 0;

  return targetm.sched.speculate_insn (insn, request, new_pat);
}

static int
haifa_speculate_insn (rtx_insn *insn, ds_t request, rtx *new_pat)
{
  gcc_assert (sched_deps_info->generate_spec_deps
	      && !IS_SPECULATION_CHECK_P (insn));

  if (HAS_INTERNAL_DEP (insn)
      || SCHED_GROUP_P (insn))
    return -1;

  return sched_speculate_insn (insn, request, new_pat);
}

/* Print some information about block BB, which starts with HEAD and
   ends with TAIL, before scheduling it.
   I is zero, if scheduler is about to start with the fresh ebb.  */
static void
dump_new_block_header (int i, basic_block bb, rtx_insn *head, rtx_insn *tail)
{
  if (!i)
    fprintf (sched_dump,
	     ";;   ======================================================\n");
  else
    fprintf (sched_dump,
	     ";;   =====================ADVANCING TO=====================\n");
  fprintf (sched_dump,
	   ";;   -- basic block %d from %d to %d -- %s reload\n",
	   bb->index, INSN_UID (head), INSN_UID (tail),
	   (reload_completed ? "after" : "before"));
  fprintf (sched_dump,
	   ";;   ======================================================\n");
  fprintf (sched_dump, "\n");
}

/* Unlink basic block notes and labels and saves them, so they
   can be easily restored.  We unlink basic block notes in EBB to
   provide back-compatibility with the previous code, as target backends
   assume, that there'll be only instructions between
   current_sched_info->{head and tail}.  We restore these notes as soon
   as we can.
   FIRST (LAST) is the first (last) basic block in the ebb.
   NB: In usual case (FIRST == LAST) nothing is really done.  */
void
unlink_bb_notes (basic_block first, basic_block last)
{
  /* We DON'T unlink basic block notes of the first block in the ebb.  */
  if (first == last)
    return;

  bb_header = XNEWVEC (rtx_insn *, last_basic_block_for_fn (cfun));

  /* Make a sentinel.  */
  if (last->next_bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
    bb_header[last->next_bb->index] = 0;

  first = first->next_bb;
  do
    {
      rtx_insn *prev, *label, *note, *next;

      label = BB_HEAD (last);
      if (LABEL_P (label))
	note = NEXT_INSN (label);
      else
	note = label;
      gcc_assert (NOTE_INSN_BASIC_BLOCK_P (note));

      prev = PREV_INSN (label);
      next = NEXT_INSN (note);
      gcc_assert (prev && next);

      SET_NEXT_INSN (prev) = next;
      SET_PREV_INSN (next) = prev;

      bb_header[last->index] = label;

      if (last == first)
	break;

      last = last->prev_bb;
    }
  while (1);
}

/* Restore basic block notes.
   FIRST is the first basic block in the ebb.  */
static void
restore_bb_notes (basic_block first)
{
  if (!bb_header)
    return;

  /* We DON'T unlink basic block notes of the first block in the ebb.  */
  first = first->next_bb;
  /* Remember: FIRST is actually a second basic block in the ebb.  */

  while (first != EXIT_BLOCK_PTR_FOR_FN (cfun)
	 && bb_header[first->index])
    {
      rtx_insn *prev, *label, *note, *next;

      label = bb_header[first->index];
      prev = PREV_INSN (label);
      next = NEXT_INSN (prev);

      if (LABEL_P (label))
	note = NEXT_INSN (label);
      else
	note = label;
      gcc_assert (NOTE_INSN_BASIC_BLOCK_P (note));

      bb_header[first->index] = 0;

      SET_NEXT_INSN (prev) = label;
      SET_NEXT_INSN (note) = next;
      SET_PREV_INSN (next) = note;

      first = first->next_bb;
    }

  free (bb_header);
  bb_header = 0;
}

/* Helper function.
   Fix CFG after both in- and inter-block movement of
   control_flow_insn_p JUMP.  */
static void
fix_jump_move (rtx_insn *jump)
{
  basic_block bb, jump_bb, jump_bb_next;

  bb = BLOCK_FOR_INSN (PREV_INSN (jump));
  jump_bb = BLOCK_FOR_INSN (jump);
  jump_bb_next = jump_bb->next_bb;

  gcc_assert (common_sched_info->sched_pass_id == SCHED_EBB_PASS
	      || IS_SPECULATION_BRANCHY_CHECK_P (jump));

  if (!NOTE_INSN_BASIC_BLOCK_P (BB_END (jump_bb_next)))
    /* if jump_bb_next is not empty.  */
    BB_END (jump_bb) = BB_END (jump_bb_next);

  if (BB_END (bb) != PREV_INSN (jump))
    /* Then there are instruction after jump that should be placed
       to jump_bb_next.  */
    BB_END (jump_bb_next) = BB_END (bb);
  else
    /* Otherwise jump_bb_next is empty.  */
    BB_END (jump_bb_next) = NEXT_INSN (BB_HEAD (jump_bb_next));

  /* To make assertion in move_insn happy.  */
  BB_END (bb) = PREV_INSN (jump);

  update_bb_for_insn (jump_bb_next);
}

/* Fix CFG after interblock movement of control_flow_insn_p JUMP.  */
static void
move_block_after_check (rtx_insn *jump)
{
  basic_block bb, jump_bb, jump_bb_next;
  vec<edge, va_gc> *t;

  bb = BLOCK_FOR_INSN (PREV_INSN (jump));
  jump_bb = BLOCK_FOR_INSN (jump);
  jump_bb_next = jump_bb->next_bb;

  update_bb_for_insn (jump_bb);

  gcc_assert (IS_SPECULATION_CHECK_P (jump)
	      || IS_SPECULATION_CHECK_P (BB_END (jump_bb_next)));

  unlink_block (jump_bb_next);
  link_block (jump_bb_next, bb);

  t = bb->succs;
  bb->succs = 0;
  move_succs (&(jump_bb->succs), bb);
  move_succs (&(jump_bb_next->succs), jump_bb);
  move_succs (&t, jump_bb_next);

  df_mark_solutions_dirty ();

  common_sched_info->fix_recovery_cfg
    (bb->index, jump_bb->index, jump_bb_next->index);
}

/* Helper function for move_block_after_check.
   This functions attaches edge vector pointed to by SUCCSP to
   block TO.  */
static void
move_succs (vec<edge, va_gc> **succsp, basic_block to)
{
  edge e;
  edge_iterator ei;

  gcc_assert (to->succs == 0);

  to->succs = *succsp;

  FOR_EACH_EDGE (e, ei, to->succs)
    e->src = to;

  *succsp = 0;
}

/* Remove INSN from the instruction stream.
   INSN should have any dependencies.  */
static void
sched_remove_insn (rtx_insn *insn)
{
  sd_finish_insn (insn);

  change_queue_index (insn, QUEUE_NOWHERE);
  current_sched_info->add_remove_insn (insn, 1);
  delete_insn (insn);
}

/* Clear priorities of all instructions, that are forward dependent on INSN.
   Store in vector pointed to by ROOTS_PTR insns on which priority () should
   be invoked to initialize all cleared priorities.  */
static void
clear_priorities (rtx_insn *insn, rtx_vec_t *roots_ptr)
{
  sd_iterator_def sd_it;
  dep_t dep;
  bool insn_is_root_p = true;

  gcc_assert (QUEUE_INDEX (insn) != QUEUE_SCHEDULED);

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

      if (INSN_PRIORITY_STATUS (pro) >= 0
	  && QUEUE_INDEX (insn) != QUEUE_SCHEDULED)
	{
	  /* If DEP doesn't contribute to priority then INSN itself should
	     be added to priority roots.  */
	  if (contributes_to_priority_p (dep))
	    insn_is_root_p = false;

	  INSN_PRIORITY_STATUS (pro) = -1;
	  clear_priorities (pro, roots_ptr);
	}
    }

  if (insn_is_root_p)
    roots_ptr->safe_push (insn);
}

/* Recompute priorities of instructions, whose priorities might have been
   changed.  ROOTS is a vector of instructions whose priority computation will
   trigger initialization of all cleared priorities.  */
static void
calc_priorities (rtx_vec_t roots)
{
  int i;
  rtx_insn *insn;

  FOR_EACH_VEC_ELT (roots, i, insn)
    priority (insn);
}


/* Add dependences between JUMP and other instructions in the recovery
   block.  INSN is the first insn the recovery block.  */
static void
add_jump_dependencies (rtx_insn *insn, rtx_insn *jump)
{
  do
    {
      insn = NEXT_INSN (insn);
      if (insn == jump)
	break;

      if (dep_list_size (insn, SD_LIST_FORW) == 0)
	{
	  dep_def _new_dep, *new_dep = &_new_dep;

	  init_dep (new_dep, insn, jump, REG_DEP_ANTI);
	  sd_add_dep (new_dep, false);
	}
    }
  while (1);

  gcc_assert (!sd_lists_empty_p (jump, SD_LIST_BACK));
}

/* Extend data structures for logical insn UID.  */
void
sched_extend_luids (void)
{
  int new_luids_max_uid = get_max_uid () + 1;

  sched_luids.safe_grow_cleared (new_luids_max_uid, true);
}

/* Initialize LUID for INSN.  */
void
sched_init_insn_luid (rtx_insn *insn)
{
  int i = INSN_P (insn) ? 1 : common_sched_info->luid_for_non_insn (insn);
  int luid;

  if (i >= 0)
    {
      luid = sched_max_luid;
      sched_max_luid += i;
    }
  else
    luid = -1;

  SET_INSN_LUID (insn, luid);
}

/* Initialize luids for BBS.
   The hook common_sched_info->luid_for_non_insn () is used to determine
   if notes, labels, etc. need luids.  */
void
sched_init_luids (bb_vec_t bbs)
{
  int i;
  basic_block bb;

  sched_extend_luids ();
  FOR_EACH_VEC_ELT (bbs, i, bb)
    {
      rtx_insn *insn;

      FOR_BB_INSNS (bb, insn)
	sched_init_insn_luid (insn);
    }
}

/* Free LUIDs.  */
void
sched_finish_luids (void)
{
  sched_luids.release ();
  sched_max_luid = 1;
}

/* Return logical uid of INSN.  Helpful while debugging.  */
int
insn_luid (rtx_insn *insn)
{
  return INSN_LUID (insn);
}

/* Extend per insn data in the target.  */
void
sched_extend_target (void)
{
  if (targetm.sched.h_i_d_extended)
    targetm.sched.h_i_d_extended ();
}

/* Extend global scheduler structures (those, that live across calls to
   schedule_block) to include information about just emitted INSN.  */
static void
extend_h_i_d (void)
{
  int reserve = (get_max_uid () + 1 - h_i_d.length ());
  if (reserve > 0
      && ! h_i_d.space (reserve))
    {
      h_i_d.safe_grow_cleared (3 * get_max_uid () / 2, true);
      sched_extend_target ();
    }
}

/* Initialize h_i_d entry of the INSN with default values.
   Values, that are not explicitly initialized here, hold zero.  */
static void
init_h_i_d (rtx_insn *insn)
{
  if (INSN_LUID (insn) > 0)
    {
      INSN_COST (insn) = -1;
      QUEUE_INDEX (insn) = QUEUE_NOWHERE;
      INSN_TICK (insn) = INVALID_TICK;
      INSN_EXACT_TICK (insn) = INVALID_TICK;
      INTER_TICK (insn) = INVALID_TICK;
      TODO_SPEC (insn) = HARD_DEP;
      INSN_AUTOPREF_MULTIPASS_DATA (insn)[0].status
	= AUTOPREF_MULTIPASS_DATA_UNINITIALIZED;
      INSN_AUTOPREF_MULTIPASS_DATA (insn)[1].status
	= AUTOPREF_MULTIPASS_DATA_UNINITIALIZED;
    }
}

/* Initialize haifa_insn_data for BBS.  */
void
haifa_init_h_i_d (bb_vec_t bbs)
{
  int i;
  basic_block bb;

  extend_h_i_d ();
  FOR_EACH_VEC_ELT (bbs, i, bb)
    {
      rtx_insn *insn;

      FOR_BB_INSNS (bb, insn)
	init_h_i_d (insn);
    }
}

/* Finalize haifa_insn_data.  */
void
haifa_finish_h_i_d (void)
{
  int i;
  haifa_insn_data_t data;
  reg_use_data *use, *next_use;
  reg_set_data *set, *next_set;

  FOR_EACH_VEC_ELT (h_i_d, i, data)
    {
      free (data->max_reg_pressure);
      free (data->reg_pressure);
      for (use = data->reg_use_list; use != NULL; use = next_use)
	{
	  next_use = use->next_insn_use;
	  free (use);
	}
      for (set = data->reg_set_list; set != NULL; set = next_set)
	{
	  next_set = set->next_insn_set;
	  free (set);
	}

    }
  h_i_d.release ();
}

/* Init data for the new insn INSN.  */
static void
haifa_init_insn (rtx_insn *insn)
{
  gcc_assert (insn != NULL);

  sched_extend_luids ();
  sched_init_insn_luid (insn);
  sched_extend_target ();
  sched_deps_init (false);
  extend_h_i_d ();
  init_h_i_d (insn);

  if (adding_bb_to_current_region_p)
    {
      sd_init_insn (insn);

      /* Extend dependency caches by one element.  */
      extend_dependency_caches (1, false);
    }
  if (sched_pressure != SCHED_PRESSURE_NONE)
    init_insn_reg_pressure_info (insn);
}

/* Init data for the new basic block BB which comes after AFTER.  */
static void
haifa_init_only_bb (basic_block bb, basic_block after)
{
  gcc_assert (bb != NULL);

  sched_init_bbs ();

  if (common_sched_info->add_block)
    /* This changes only data structures of the front-end.  */
    common_sched_info->add_block (bb, after);
}

/* A generic version of sched_split_block ().  */
basic_block
sched_split_block_1 (basic_block first_bb, rtx after)
{
  edge e;

  e = split_block (first_bb, after);
  gcc_assert (e->src == first_bb);

  /* sched_split_block emits note if *check == BB_END.  Probably it
     is better to rip that note off.  */

  return e->dest;
}

/* A generic version of sched_create_empty_bb ().  */
basic_block
sched_create_empty_bb_1 (basic_block after)
{
  return create_empty_bb (after);
}

/* Insert PAT as an INSN into the schedule and update the necessary data
   structures to account for it. */
rtx_insn *
sched_emit_insn (rtx pat)
{
  rtx_insn *insn = emit_insn_before (pat, first_nonscheduled_insn ());
  haifa_init_insn (insn);

  if (current_sched_info->add_remove_insn)
    current_sched_info->add_remove_insn (insn, 0);

  (*current_sched_info->begin_schedule_ready) (insn);
  scheduled_insns.safe_push (insn);

  last_scheduled_insn = insn;
  return insn;
}

/* This function returns a candidate satisfying dispatch constraints from
   the ready list.  */

static rtx_insn *
ready_remove_first_dispatch (struct ready_list *ready)
{
  int i;
  rtx_insn *insn = ready_element (ready, 0);

  if (ready->n_ready == 1
      || !INSN_P (insn)
      || INSN_CODE (insn) < 0
      || !active_insn_p (insn)
      || targetm.sched.dispatch (insn, FITS_DISPATCH_WINDOW))
    return ready_remove_first (ready);

  for (i = 1; i < ready->n_ready; i++)
    {
      insn = ready_element (ready, i);

      if (!INSN_P (insn)
	  || INSN_CODE (insn) < 0
	  || !active_insn_p (insn))
	continue;

      if (targetm.sched.dispatch (insn, FITS_DISPATCH_WINDOW))
	{
	  /* Return ith element of ready.  */
	  insn = ready_remove (ready, i);
	  return insn;
	}
    }

  if (targetm.sched.dispatch (NULL, DISPATCH_VIOLATION))
    return ready_remove_first (ready);

  for (i = 1; i < ready->n_ready; i++)
    {
      insn = ready_element (ready, i);

      if (!INSN_P (insn)
	  || INSN_CODE (insn) < 0
	  || !active_insn_p (insn))
	continue;

      /* Return i-th element of ready.  */
      if (targetm.sched.dispatch (insn, IS_CMP))
	return ready_remove (ready, i);
    }

  return ready_remove_first (ready);
}

/* Get number of ready insn in the ready list.  */

int
number_in_ready (void)
{
  return ready.n_ready;
}

/* Get number of ready's in the ready list.  */

rtx_insn *
get_ready_element (int i)
{
  return ready_element (&ready, i);
}

#endif /* INSN_SCHEDULING */
