/* Instruction scheduling pass.  Selective scheduler and pipeliner.
   Copyright (C) 2006-2018 Free Software Foundation, Inc.

This file is part of GCC.

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

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

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

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "rtl.h"
#include "df.h"
#include "memmodel.h"
#include "tm_p.h"
#include "regs.h"
#include "cfgbuild.h"
#include "cfgcleanup.h"
#include "insn-config.h"
#include "insn-attr.h"
#include "params.h"
#include "target.h"
#include "sched-int.h"
#include "rtlhooks-def.h"
#include "ira.h"
#include "ira-int.h"
#include "rtl-iter.h"

#ifdef INSN_SCHEDULING
#include "regset.h"
#include "cfgloop.h"
#include "sel-sched-ir.h"
#include "sel-sched-dump.h"
#include "sel-sched.h"
#include "dbgcnt.h"

/* Implementation of selective scheduling approach.
   The below implementation follows the original approach with the following
   changes:

   o the scheduler works after register allocation (but can be also tuned
   to work before RA);
   o some instructions are not copied or register renamed;
   o conditional jumps are not moved with code duplication;
   o several jumps in one parallel group are not supported;
   o when pipelining outer loops, code motion through inner loops
   is not supported;
   o control and data speculation are supported;
   o some improvements for better compile time/performance were made.

   Terminology
   ===========

   A vinsn, or virtual insn, is an insn with additional data characterizing
   insn pattern, such as LHS, RHS, register sets used/set/clobbered, etc.
   Vinsns also act as smart pointers to save memory by reusing them in
   different expressions.  A vinsn is described by vinsn_t type.

   An expression is a vinsn with additional data characterizing its properties
   at some point in the control flow graph.  The data may be its usefulness,
   priority, speculative status, whether it was renamed/subsituted, etc.
   An expression is described by expr_t type.

   Availability set (av_set) is a set of expressions at a given control flow
   point. It is represented as av_set_t.  The expressions in av sets are kept
   sorted in the terms of expr_greater_p function.  It allows to truncate
   the set while leaving the best expressions.

   A fence is a point through which code motion is prohibited.  On each step,
   we gather a parallel group of insns at a fence.  It is possible to have
   multiple fences. A fence is represented via fence_t.

   A boundary is the border between the fence group and the rest of the code.
   Currently, we never have more than one boundary per fence, as we finalize
   the fence group when a jump is scheduled. A boundary is represented
   via bnd_t.

   High-level overview
   ===================

   The scheduler finds regions to schedule, schedules each one, and finalizes.
   The regions are formed starting from innermost loops, so that when the inner
   loop is pipelined, its prologue can be scheduled together with yet unprocessed
   outer loop. The rest of acyclic regions are found using extend_rgns:
   the blocks that are not yet allocated to any regions are traversed in top-down
   order, and a block is added to a region to which all its predecessors belong;
   otherwise, the block starts its own region.

   The main scheduling loop (sel_sched_region_2) consists of just
   scheduling on each fence and updating fences.  For each fence,
   we fill a parallel group of insns (fill_insns) until some insns can be added.
   First, we compute available exprs (av-set) at the boundary of the current
   group.  Second, we choose the best expression from it.  If the stall is
   required to schedule any of the expressions, we advance the current cycle
   appropriately.  So, the final group does not exactly correspond to a VLIW
   word.  Third, we move the chosen expression to the boundary (move_op)
   and update the intermediate av sets and liveness sets.  We quit fill_insns
   when either no insns left for scheduling or we have scheduled enough insns
   so we feel like advancing a scheduling point.

   Computing available expressions
   ===============================

   The computation (compute_av_set) is a bottom-up traversal.  At each insn,
   we're moving the union of its successors' sets through it via
   moveup_expr_set.  The dependent expressions are removed.  Local
   transformations (substitution, speculation) are applied to move more
   exprs.  Then the expr corresponding to the current insn is added.
   The result is saved on each basic block header.

   When traversing the CFG, we're moving down for no more than max_ws insns.
   Also, we do not move down to ineligible successors (is_ineligible_successor),
   which include moving along a back-edge, moving to already scheduled code,
   and moving to another fence.  The first two restrictions are lifted during
   pipelining, which allows us to move insns along a back-edge.  We always have
   an acyclic region for scheduling because we forbid motion through fences.

   Choosing the best expression
   ============================

   We sort the final availability set via sel_rank_for_schedule, then we remove
   expressions which are not yet ready (tick_check_p) or which dest registers
   cannot be used.  For some of them, we choose another register via
   find_best_reg.  To do this, we run find_used_regs to calculate the set of
   registers which cannot be used.  The find_used_regs function performs
   a traversal of code motion paths for an expr.  We consider for renaming
   only registers which are from the same regclass as the original one and
   using which does not interfere with any live ranges.  Finally, we convert
   the resulting set to the ready list format and use max_issue and reorder*
   hooks similarly to the Haifa scheduler.

   Scheduling the best expression
   ==============================

   We run the move_op routine to perform the same type of code motion paths
   traversal as in find_used_regs.  (These are working via the same driver,
   code_motion_path_driver.)  When moving down the CFG, we look for original
   instruction that gave birth to a chosen expression.  We undo
   the transformations performed on an expression via the history saved in it.
   When found, we remove the instruction or leave a reg-reg copy/speculation
   check if needed.  On a way up, we insert bookkeeping copies at each join
   point.  If a copy is not needed, it will be removed later during this
   traversal.  We update the saved av sets and liveness sets on the way up, too.

   Finalizing the schedule
   =======================

   When pipelining, we reschedule the blocks from which insns were pipelined
   to get a tighter schedule.  On Itanium, we also perform bundling via
   the same routine from ia64.c.

   Dependence analysis changes
   ===========================

   We augmented the sched-deps.c with hooks that get called when a particular
   dependence is found in a particular part of an insn.  Using these hooks, we
   can do several actions such as: determine whether an insn can be moved through
   another (has_dependence_p, moveup_expr); find out whether an insn can be
   scheduled on the current cycle (tick_check_p); find out registers that
   are set/used/clobbered by an insn and find out all the strange stuff that
   restrict its movement, like SCHED_GROUP_P or CANT_MOVE (done in
   init_global_and_expr_for_insn).

   Initialization changes
   ======================

   There are parts of haifa-sched.c, sched-deps.c, and sched-rgn.c that are
   reused in all of the schedulers.  We have split up the initialization of data
   of such parts into different functions prefixed with scheduler type and
   postfixed with the type of data initialized: {,sel_,haifa_}sched_{init,finish},
   sched_rgn_init/finish, sched_deps_init/finish, sched_init_{luids/bbs}, etc.
   The same splitting is done with current_sched_info structure:
   dependence-related parts are in sched_deps_info, common part is in
   common_sched_info, and haifa/sel/etc part is in current_sched_info.

   Target contexts
   ===============

   As we now have multiple-point scheduling, this would not work with backends
   which save some of the scheduler state to use it in the target hooks.
   For this purpose, we introduce a concept of target contexts, which
   encapsulate such information.  The backend should implement simple routines
   of allocating/freeing/setting such a context.  The scheduler calls these
   as target hooks and handles the target context as an opaque pointer (similar
   to the DFA state type, state_t).

   Various speedups
   ================

   As the correct data dependence graph is not supported during scheduling (which
   is to be changed in mid-term), we cache as much of the dependence analysis
   results as possible to avoid reanalyzing.  This includes: bitmap caches on
   each insn in stream of the region saying yes/no for a query with a pair of
   UIDs; hashtables with the previously done transformations on each insn in
   stream; a vector keeping a history of transformations on each expr.

   Also, we try to minimize the dependence context used on each fence to check
   whether the given expression is ready for scheduling by removing from it
   insns that are definitely completed the execution.  The results of
   tick_check_p checks are also cached in a vector on each fence.

   We keep a valid liveness set on each insn in a region to avoid the high
   cost of recomputation on large basic blocks.

   Finally, we try to minimize the number of needed updates to the availability
   sets.  The updates happen in two cases: when fill_insns terminates,
   we advance all fences and increase the stage number to show that the region
   has changed and the sets are to be recomputed; and when the next iteration
   of a loop in fill_insns happens (but this one reuses the saved av sets
   on bb headers.)  Thus, we try to break the fill_insns loop only when
   "significant" number of insns from the current scheduling window was
   scheduled.  This should be made a target param.


   TODO: correctly support the data dependence graph at all stages and get rid
   of all caches.  This should speed up the scheduler.
   TODO: implement moving cond jumps with bookkeeping copies on both targets.
   TODO: tune the scheduler before RA so it does not create too much pseudos.


   References:
   S.-M. Moon and K. Ebcioglu. Parallelizing nonnumerical code with
   selective scheduling and software pipelining.
   ACM TOPLAS, Vol 19, No. 6, pages 853--898, Nov. 1997.

   Andrey Belevantsev, Maxim Kuvyrkov, Vladimir Makarov, Dmitry Melnik,
   and Dmitry Zhurikhin.  An interblock VLIW-targeted instruction scheduler
   for GCC. In Proceedings of GCC Developers' Summit 2006.

   Arutyun Avetisyan, Andrey Belevantsev, and Dmitry Melnik.  GCC Instruction
   Scheduler and Software Pipeliner on the Itanium Platform.   EPIC-7 Workshop.
   http://rogue.colorado.edu/EPIC7/.

*/

/* True when pipelining is enabled.  */
bool pipelining_p;

/* True if bookkeeping is enabled.  */
bool bookkeeping_p;

/* Maximum number of insns that are eligible for renaming.  */
int max_insns_to_rename;


/* Definitions of local types and macros.  */

/* Represents possible outcomes of moving an expression through an insn.  */
enum MOVEUP_EXPR_CODE
  {
    /* The expression is not changed.  */
    MOVEUP_EXPR_SAME,

    /* Not changed, but requires a new destination register.  */
    MOVEUP_EXPR_AS_RHS,

    /* Cannot be moved.  */
    MOVEUP_EXPR_NULL,

    /* Changed (substituted or speculated).  */
    MOVEUP_EXPR_CHANGED
  };

/* The container to be passed into rtx search & replace functions.  */
struct rtx_search_arg
{
  /* What we are searching for.  */
  rtx x;

  /* The occurrence counter.  */
  int n;
};

typedef struct rtx_search_arg *rtx_search_arg_p;

/* This struct contains precomputed hard reg sets that are needed when
   computing registers available for renaming.  */
struct hard_regs_data
{
  /* For every mode, this stores registers available for use with
     that mode.  */
  HARD_REG_SET regs_for_mode[NUM_MACHINE_MODES];

  /* True when regs_for_mode[mode] is initialized.  */
  bool regs_for_mode_ok[NUM_MACHINE_MODES];

  /* For every register, it has regs that are ok to rename into it.
     The register in question is always set.  If not, this means
     that the whole set is not computed yet.  */
  HARD_REG_SET regs_for_rename[FIRST_PSEUDO_REGISTER];

  /* For every mode, this stores registers not available due to
     call clobbering.  */
  HARD_REG_SET regs_for_call_clobbered[NUM_MACHINE_MODES];

  /* All registers that are used or call used.  */
  HARD_REG_SET regs_ever_used;

#ifdef STACK_REGS
  /* Stack registers.  */
  HARD_REG_SET stack_regs;
#endif
};

/* Holds the results of computation of available for renaming and
   unavailable hard registers.  */
struct reg_rename
{
  /* These are unavailable due to calls crossing, globalness, etc.  */
  HARD_REG_SET unavailable_hard_regs;

  /* These are *available* for renaming.  */
  HARD_REG_SET available_for_renaming;

  /* Whether this code motion path crosses a call.  */
  bool crosses_call;
};

/* A global structure that contains the needed information about harg
   regs.  */
static struct hard_regs_data sel_hrd;


/* This structure holds local data used in code_motion_path_driver hooks on
   the same or adjacent levels of recursion.  Here we keep those parameters
   that are not used in code_motion_path_driver routine itself, but only in
   its hooks.  Moreover, all parameters that can be modified in hooks are
   in this structure, so all other parameters passed explicitly to hooks are
   read-only.  */
struct cmpd_local_params
{
  /* Local params used in move_op_* functions.  */

  /* Edges for bookkeeping generation.  */
  edge e1, e2;

  /* C_EXPR merged from all successors and locally allocated temporary C_EXPR.  */
  expr_t c_expr_merged, c_expr_local;

  /* Local params used in fur_* functions.  */
  /* Copy of the ORIGINAL_INSN list, stores the original insns already
     found before entering the current level of code_motion_path_driver.  */
  def_list_t old_original_insns;

  /* Local params used in move_op_* functions.  */
  /* True when we have removed last insn in the block which was
     also a boundary.  Do not update anything or create bookkeeping copies.  */
  BOOL_BITFIELD removed_last_insn : 1;
};

/* Stores the static parameters for move_op_* calls.  */
struct moveop_static_params
{
  /* Destination register.  */
  rtx dest;

  /* Current C_EXPR.  */
  expr_t c_expr;

  /* An UID of expr_vliw which is to be moved up.  If we find other exprs,
     they are to be removed.  */
  int uid;

  /* This is initialized to the insn on which the driver stopped its traversal.  */
  insn_t failed_insn;

  /* True if we scheduled an insn with different register.  */
  bool was_renamed;
};

/* Stores the static parameters for fur_* calls.  */
struct fur_static_params
{
  /* Set of registers unavailable on the code motion path.  */
  regset used_regs;

  /* Pointer to the list of original insns definitions.  */
  def_list_t *original_insns;

  /* True if a code motion path contains a CALL insn.  */
  bool crosses_call;
};

typedef struct fur_static_params *fur_static_params_p;
typedef struct cmpd_local_params *cmpd_local_params_p;
typedef struct moveop_static_params *moveop_static_params_p;

/* Set of hooks and parameters that determine behavior specific to
   move_op or find_used_regs functions.  */
struct code_motion_path_driver_info_def
{
  /* Called on enter to the basic block.  */
  int (*on_enter) (insn_t, cmpd_local_params_p, void *, bool);

  /* Called when original expr is found.  */
  void (*orig_expr_found) (insn_t, expr_t, cmpd_local_params_p, void *);

  /* Called while descending current basic block if current insn is not
     the original EXPR we're searching for.  */
  bool (*orig_expr_not_found) (insn_t, av_set_t, void *);

  /* Function to merge C_EXPRes from different successors.  */
  void (*merge_succs) (insn_t, insn_t, int, cmpd_local_params_p, void *);

  /* Function to finalize merge from different successors and possibly
     deallocate temporary data structures used for merging.  */
  void (*after_merge_succs) (cmpd_local_params_p, void *);

  /* Called on the backward stage of recursion to do moveup_expr.
     Used only with move_op_*.  */
  void (*ascend) (insn_t, void *);

  /* Called on the ascending pass, before returning from the current basic
     block or from the whole traversal.  */
  void (*at_first_insn) (insn_t, cmpd_local_params_p, void *);

  /* When processing successors in move_op we need only descend into
     SUCCS_NORMAL successors, while in find_used_regs we need SUCCS_ALL.  */
  int succ_flags;

  /* The routine name to print in dumps ("move_op" of "find_used_regs").  */
  const char *routine_name;
};

/* Global pointer to current hooks, either points to MOVE_OP_HOOKS or
   FUR_HOOKS.  */
struct code_motion_path_driver_info_def *code_motion_path_driver_info;

/* Set of hooks for performing move_op and find_used_regs routines with
   code_motion_path_driver.  */
extern struct code_motion_path_driver_info_def move_op_hooks, fur_hooks;

/* True if/when we want to emulate Haifa scheduler in the common code.
   This is used in sched_rgn_local_init and in various places in
   sched-deps.c.  */
int sched_emulate_haifa_p;

/* GLOBAL_LEVEL is used to discard information stored in basic block headers
   av_sets.  Av_set of bb header is valid if its (bb header's) level is equal
   to GLOBAL_LEVEL.  And invalid if lesser.  This is primarily used to advance
   scheduling window.  */
int global_level;

/* Current fences.  */
flist_t fences;

/* True when separable insns should be scheduled as RHSes.  */
static bool enable_schedule_as_rhs_p;

/* Used in verify_target_availability to assert that target reg is reported
   unavailabile by both TARGET_UNAVAILABLE and find_used_regs only if
   we haven't scheduled anything on the previous fence.
   if scheduled_something_on_previous_fence is true, TARGET_UNAVAILABLE can
   have more conservative value than the one returned by the
   find_used_regs, thus we shouldn't assert that these values are equal.  */
static bool scheduled_something_on_previous_fence;

/* All newly emitted insns will have their uids greater than this value.  */
static int first_emitted_uid;

/* Set of basic blocks that are forced to start new ebbs.  This is a subset
   of all the ebb heads.  */
static bitmap_head _forced_ebb_heads;
bitmap_head *forced_ebb_heads = &_forced_ebb_heads;

/* Blocks that need to be rescheduled after pipelining.  */
bitmap blocks_to_reschedule = NULL;

/* True when the first lv set should be ignored when updating liveness.  */
static bool ignore_first = false;

/* Number of insns max_issue has initialized data structures for.  */
static int max_issue_size = 0;

/* Whether we can issue more instructions.  */
static int can_issue_more;

/* Maximum software lookahead window size, reduced when rescheduling after
   pipelining.  */
static int max_ws;

/* Number of insns scheduled in current region.  */
static int num_insns_scheduled;

/* A vector of expressions is used to be able to sort them.  */
static vec<expr_t> vec_av_set;

/* A vector of vinsns is used to hold temporary lists of vinsns.  */
typedef vec<vinsn_t> vinsn_vec_t;

/* This vector has the exprs which may still present in av_sets, but actually
   can't be moved up due to bookkeeping created during code motion to another
   fence.  See comment near the call to update_and_record_unavailable_insns
   for the detailed explanations.  */
static vinsn_vec_t vec_bookkeeping_blocked_vinsns = vinsn_vec_t ();

/* This vector has vinsns which are scheduled with renaming on the first fence
   and then seen on the second.  For expressions with such vinsns, target
   availability information may be wrong.  */
static vinsn_vec_t vec_target_unavailable_vinsns = vinsn_vec_t ();

/* Vector to store temporary nops inserted in move_op to prevent removal
   of empty bbs.  */
static vec<insn_t> vec_temp_moveop_nops;

/* These bitmaps record original instructions scheduled on the current
   iteration and bookkeeping copies created by them.  */
static bitmap current_originators = NULL;
static bitmap current_copies = NULL;

/* This bitmap marks the blocks visited by code_motion_path_driver so we don't
   visit them afterwards.  */
static bitmap code_motion_visited_blocks = NULL;

/* Variables to accumulate different statistics.  */

/* The number of bookkeeping copies created.  */
static int stat_bookkeeping_copies;

/* The number of insns that required bookkeeiping for their scheduling.  */
static int stat_insns_needed_bookkeeping;

/* The number of insns that got renamed.  */
static int stat_renamed_scheduled;

/* The number of substitutions made during scheduling.  */
static int stat_substitutions_total;


/* Forward declarations of static functions.  */
static bool rtx_ok_for_substitution_p (rtx, rtx);
static int sel_rank_for_schedule (const void *, const void *);
static av_set_t find_sequential_best_exprs (bnd_t, expr_t, bool);
static basic_block find_block_for_bookkeeping (edge e1, edge e2, bool lax);

static rtx get_dest_from_orig_ops (av_set_t);
static basic_block generate_bookkeeping_insn (expr_t, edge, edge);
static bool find_used_regs (insn_t, av_set_t, regset, struct reg_rename *,
                            def_list_t *);
static bool move_op (insn_t, av_set_t, expr_t, rtx, expr_t, bool*);
static int code_motion_path_driver (insn_t, av_set_t, ilist_t,
                                    cmpd_local_params_p, void *);
static void sel_sched_region_1 (void);
static void sel_sched_region_2 (int);
static av_set_t compute_av_set_inside_bb (insn_t, ilist_t, int, bool);

static void debug_state (state_t);


/* Functions that work with fences.  */

/* Advance one cycle on FENCE.  */
static void
advance_one_cycle (fence_t fence)
{
  unsigned i;
  int cycle;
  rtx_insn *insn;

  advance_state (FENCE_STATE (fence));
  cycle = ++FENCE_CYCLE (fence);
  FENCE_ISSUED_INSNS (fence) = 0;
  FENCE_STARTS_CYCLE_P (fence) = 1;
  can_issue_more = issue_rate;
  FENCE_ISSUE_MORE (fence) = can_issue_more;

  for (i = 0; vec_safe_iterate (FENCE_EXECUTING_INSNS (fence), i, &insn); )
    {
      if (INSN_READY_CYCLE (insn) < cycle)
        {
          remove_from_deps (FENCE_DC (fence), insn);
          FENCE_EXECUTING_INSNS (fence)->unordered_remove (i);
          continue;
        }
      i++;
    }
  if (sched_verbose >= 2)
    {
      sel_print ("Finished a cycle.  Current cycle = %d\n", FENCE_CYCLE (fence));
      debug_state (FENCE_STATE (fence));
    }
}

/* Returns true when SUCC in a fallthru bb of INSN, possibly
   skipping empty basic blocks.  */
static bool
in_fallthru_bb_p (rtx_insn *insn, rtx succ)
{
  basic_block bb = BLOCK_FOR_INSN (insn);
  edge e;

  if (bb == BLOCK_FOR_INSN (succ))
    return true;

  e = find_fallthru_edge_from (bb);
  if (e)
    bb = e->dest;
  else
    return false;

  while (sel_bb_empty_p (bb))
    bb = bb->next_bb;

  return bb == BLOCK_FOR_INSN (succ);
}

/* Construct successor fences from OLD_FENCEs and put them in NEW_FENCES.
   When a successor will continue a ebb, transfer all parameters of a fence
   to the new fence.  ORIG_MAX_SEQNO is the maximal seqno before this round
   of scheduling helping to distinguish between the old and the new code.  */
static void
extract_new_fences_from (flist_t old_fences, flist_tail_t new_fences,
			 int orig_max_seqno)
{
  bool was_here_p = false;
  insn_t insn = NULL;
  insn_t succ;
  succ_iterator si;
  ilist_iterator ii;
  fence_t fence = FLIST_FENCE (old_fences);
  basic_block bb;

  /* Get the only element of FENCE_BNDS (fence).  */
  FOR_EACH_INSN (insn, ii, FENCE_BNDS (fence))
    {
      gcc_assert (!was_here_p);
      was_here_p = true;
    }
  gcc_assert (was_here_p && insn != NULL_RTX);

  /* When in the "middle" of the block, just move this fence
     to the new list.  */
  bb = BLOCK_FOR_INSN (insn);
  if (! sel_bb_end_p (insn)
      || (single_succ_p (bb)
          && single_pred_p (single_succ (bb))))
    {
      insn_t succ;

      succ = (sel_bb_end_p (insn)
              ? sel_bb_head (single_succ (bb))
              : NEXT_INSN (insn));

      if (INSN_SEQNO (succ) > 0
          && INSN_SEQNO (succ) <= orig_max_seqno
          && INSN_SCHED_TIMES (succ) <= 0)
        {
          FENCE_INSN (fence) = succ;
          move_fence_to_fences (old_fences, new_fences);

          if (sched_verbose >= 1)
            sel_print ("Fence %d continues as %d[%d] (state continue)\n",
                       INSN_UID (insn), INSN_UID (succ), BLOCK_NUM (succ));
        }
      return;
    }

  /* Otherwise copy fence's structures to (possibly) multiple successors.  */
  FOR_EACH_SUCC_1 (succ, si, insn, SUCCS_NORMAL | SUCCS_SKIP_TO_LOOP_EXITS)
    {
      int seqno = INSN_SEQNO (succ);

      if (seqno > 0 && seqno <= orig_max_seqno
          && (pipelining_p || INSN_SCHED_TIMES (succ) <= 0))
        {
          bool b = (in_same_ebb_p (insn, succ)
                    || in_fallthru_bb_p (insn, succ));

          if (sched_verbose >= 1)
            sel_print ("Fence %d continues as %d[%d] (state %s)\n",
                       INSN_UID (insn), INSN_UID (succ),
                       BLOCK_NUM (succ), b ? "continue" : "reset");

          if (b)
            add_dirty_fence_to_fences (new_fences, succ, fence);
          else
            {
              /* Mark block of the SUCC as head of the new ebb.  */
              bitmap_set_bit (forced_ebb_heads, BLOCK_NUM (succ));
              add_clean_fence_to_fences (new_fences, succ, fence);
            }
        }
    }
}


/* Functions to support substitution.  */

/* Returns whether INSN with dependence status DS is eligible for
   substitution, i.e. it's a copy operation x := y, and RHS that is
   moved up through this insn should be substituted.  */
static bool
can_substitute_through_p (insn_t insn, ds_t ds)
{
  /* We can substitute only true dependencies.  */
  if ((ds & DEP_OUTPUT)
      || (ds & DEP_ANTI)
      || ! INSN_RHS (insn)
      || ! INSN_LHS (insn))
    return false;

  /* Now we just need to make sure the INSN_RHS consists of only one
     simple REG rtx.  */
  if (REG_P (INSN_LHS (insn))
      && REG_P (INSN_RHS (insn)))
    return true;
  return false;
}

/* Substitute all occurrences of INSN's destination in EXPR' vinsn with INSN's
   source (if INSN is eligible for substitution).  Returns TRUE if
   substitution was actually performed, FALSE otherwise.  Substitution might
   be not performed because it's either EXPR' vinsn doesn't contain INSN's
   destination or the resulting insn is invalid for the target machine.
   When UNDO is true, perform unsubstitution instead (the difference is in
   the part of rtx on which validate_replace_rtx is called).  */
static bool
substitute_reg_in_expr (expr_t expr, insn_t insn, bool undo)
{
  rtx *where;
  bool new_insn_valid;
  vinsn_t *vi = &EXPR_VINSN (expr);
  bool has_rhs = VINSN_RHS (*vi) != NULL;
  rtx old, new_rtx;

  /* Do not try to replace in SET_DEST.  Although we'll choose new
     register for the RHS, we don't want to change RHS' original reg.
     If the insn is not SET, we may still be able to substitute something
     in it, and if we're here (don't have deps), it doesn't write INSN's
     dest.  */
  where = (has_rhs
	   ? &VINSN_RHS (*vi)
	   : &PATTERN (VINSN_INSN_RTX (*vi)));
  old = undo ? INSN_RHS (insn) : INSN_LHS (insn);

  /* Substitute if INSN has a form of x:=y and LHS(INSN) occurs in *VI.  */
  if (rtx_ok_for_substitution_p (old, *where))
    {
      rtx_insn *new_insn;
      rtx *where_replace;

      /* We should copy these rtxes before substitution.  */
      new_rtx = copy_rtx (undo ? INSN_LHS (insn) : INSN_RHS (insn));
      new_insn = create_copy_of_insn_rtx (VINSN_INSN_RTX (*vi));

      /* Where we'll replace.
         WHERE_REPLACE should point inside NEW_INSN, so INSN_RHS couldn't be
	 used instead of SET_SRC.  */
      where_replace = (has_rhs
		       ? &SET_SRC (PATTERN (new_insn))
		       : &PATTERN (new_insn));

      new_insn_valid
        = validate_replace_rtx_part_nosimplify (old, new_rtx, where_replace,
                                                new_insn);

      /* ??? Actually, constrain_operands result depends upon choice of
         destination register.  E.g. if we allow single register to be an rhs,
	 and if we try to move dx=ax(as rhs) through ax=dx, we'll result
	 in invalid insn dx=dx, so we'll loose this rhs here.
	 Just can't come up with significant testcase for this, so just
	 leaving it for now.  */
      if (new_insn_valid)
	{
	  change_vinsn_in_expr (expr,
				create_vinsn_from_insn_rtx (new_insn, false));

	  /* Do not allow clobbering the address register of speculative
             insns.  */
	  if ((EXPR_SPEC_DONE_DS (expr) & SPECULATIVE)
              && register_unavailable_p (VINSN_REG_USES (EXPR_VINSN (expr)),
					 expr_dest_reg (expr)))
	    EXPR_TARGET_AVAILABLE (expr) = false;

	  return true;
	}
      else
        return false;
    }
  else
    return false;
}

/* Return the number of places WHAT appears within WHERE.
   Bail out when we found a reference occupying several hard registers.  */
static int
count_occurrences_equiv (const_rtx what, const_rtx where)
{
  int count = 0;
  subrtx_iterator::array_type array;
  FOR_EACH_SUBRTX (iter, array, where, NONCONST)
    {
      const_rtx x = *iter;
      if (REG_P (x) && REGNO (x) == REGNO (what))
	{
	  /* Bail out if mode is different or more than one register is
	     used.  */
	  if (GET_MODE (x) != GET_MODE (what) || REG_NREGS (x) > 1)
	    return 0;
	  count += 1;
	}
      else if (GET_CODE (x) == SUBREG
	       && (!REG_P (SUBREG_REG (x))
		   || REGNO (SUBREG_REG (x)) == REGNO (what)))
	/* ??? Do not support substituting regs inside subregs.  In that case,
	   simplify_subreg will be called by validate_replace_rtx, and
	   unsubstitution will fail later.  */
	return 0;
    }
  return count;
}

/* Returns TRUE if WHAT is found in WHERE rtx tree.  */
static bool
rtx_ok_for_substitution_p (rtx what, rtx where)
{
  return (count_occurrences_equiv (what, where) > 0);
}


/* Functions to support register renaming.  */

/* Substitute VI's set source with REGNO.  Returns newly created pattern
   that has REGNO as its source.  */
static rtx_insn *
create_insn_rtx_with_rhs (vinsn_t vi, rtx rhs_rtx)
{
  rtx lhs_rtx;
  rtx pattern;
  rtx_insn *insn_rtx;

  lhs_rtx = copy_rtx (VINSN_LHS (vi));

  pattern = gen_rtx_SET (lhs_rtx, rhs_rtx);
  insn_rtx = create_insn_rtx_from_pattern (pattern, NULL_RTX);

  return insn_rtx;
}

/* Returns whether INSN's src can be replaced with register number
   NEW_SRC_REG. E.g. the following insn is valid for i386:

    (insn:HI 2205 6585 2207 727 ../../gcc/libiberty/regex.c:3337
      (set (mem/s:QI (plus:SI (plus:SI (reg/f:SI 7 sp)
			(reg:SI 0 ax [orig:770 c1 ] [770]))
		    (const_int 288 [0x120])) [0 str S1 A8])
	    (const_int 0 [0x0])) 43 {*movqi_1} (nil)
	(nil))

  But if we change (const_int 0 [0x0]) to (reg:QI 4 si), it will be invalid
  because of operand constraints:

    (define_insn "*movqi_1"
      [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
	    (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn")
	    )]

  So do constrain_operands here, before choosing NEW_SRC_REG as best
  reg for rhs.  */

static bool
replace_src_with_reg_ok_p (insn_t insn, rtx new_src_reg)
{
  vinsn_t vi = INSN_VINSN (insn);
  machine_mode mode;
  rtx dst_loc;
  bool res;

  gcc_assert (VINSN_SEPARABLE_P (vi));

  get_dest_and_mode (insn, &dst_loc, &mode);
  gcc_assert (mode == GET_MODE (new_src_reg));

  if (REG_P (dst_loc) && REGNO (new_src_reg) == REGNO (dst_loc))
    return true;

  /* See whether SET_SRC can be replaced with this register.  */
  validate_change (insn, &SET_SRC (PATTERN (insn)), new_src_reg, 1);
  res = verify_changes (0);
  cancel_changes (0);

  return res;
}

/* Returns whether INSN still be valid after replacing it's DEST with
   register NEW_REG.  */
static bool
replace_dest_with_reg_ok_p (insn_t insn, rtx new_reg)
{
  vinsn_t vi = INSN_VINSN (insn);
  bool res;

  /* We should deal here only with separable insns.  */
  gcc_assert (VINSN_SEPARABLE_P (vi));
  gcc_assert (GET_MODE (VINSN_LHS (vi)) == GET_MODE (new_reg));

  /* See whether SET_DEST can be replaced with this register.  */
  validate_change (insn, &SET_DEST (PATTERN (insn)), new_reg, 1);
  res = verify_changes (0);
  cancel_changes (0);

  return res;
}

/* Create a pattern with rhs of VI and lhs of LHS_RTX.  */
static rtx_insn *
create_insn_rtx_with_lhs (vinsn_t vi, rtx lhs_rtx)
{
  rtx rhs_rtx;
  rtx pattern;
  rtx_insn *insn_rtx;

  rhs_rtx = copy_rtx (VINSN_RHS (vi));

  pattern = gen_rtx_SET (lhs_rtx, rhs_rtx);
  insn_rtx = create_insn_rtx_from_pattern (pattern, NULL_RTX);

  return insn_rtx;
}

/* Substitute lhs in the given expression EXPR for the register with number
   NEW_REGNO.  SET_DEST may be arbitrary rtx, not only register.  */
static void
replace_dest_with_reg_in_expr (expr_t expr, rtx new_reg)
{
  rtx_insn *insn_rtx;
  vinsn_t vinsn;

  insn_rtx = create_insn_rtx_with_lhs (EXPR_VINSN (expr), new_reg);
  vinsn = create_vinsn_from_insn_rtx (insn_rtx, false);

  change_vinsn_in_expr (expr, vinsn);
  EXPR_WAS_RENAMED (expr) = 1;
  EXPR_TARGET_AVAILABLE (expr) = 1;
}

/* Returns whether VI writes either one of the USED_REGS registers or,
   if a register is a hard one, one of the UNAVAILABLE_HARD_REGS registers.  */
static bool
vinsn_writes_one_of_regs_p (vinsn_t vi, regset used_regs,
                            HARD_REG_SET unavailable_hard_regs)
{
  unsigned regno;
  reg_set_iterator rsi;

  EXECUTE_IF_SET_IN_REG_SET (VINSN_REG_SETS (vi), 0, regno, rsi)
    {
      if (REGNO_REG_SET_P (used_regs, regno))
        return true;
      if (HARD_REGISTER_NUM_P (regno)
          && TEST_HARD_REG_BIT (unavailable_hard_regs, regno))
	return true;
    }

  EXECUTE_IF_SET_IN_REG_SET (VINSN_REG_CLOBBERS (vi), 0, regno, rsi)
    {
      if (REGNO_REG_SET_P (used_regs, regno))
        return true;
      if (HARD_REGISTER_NUM_P (regno)
          && TEST_HARD_REG_BIT (unavailable_hard_regs, regno))
	return true;
    }

  return false;
}

/* Returns register class of the output register in INSN.
   Returns NO_REGS for call insns because some targets have constraints on
   destination register of a call insn.

   Code adopted from regrename.c::build_def_use.  */
static enum reg_class
get_reg_class (rtx_insn *insn)
{
  int i, n_ops;

  extract_constrain_insn (insn);
  preprocess_constraints (insn);
  n_ops = recog_data.n_operands;

  const operand_alternative *op_alt = which_op_alt ();
  if (asm_noperands (PATTERN (insn)) > 0)
    {
      for (i = 0; i < n_ops; i++)
	if (recog_data.operand_type[i] == OP_OUT)
	  {
	    rtx *loc = recog_data.operand_loc[i];
	    rtx op = *loc;
	    enum reg_class cl = alternative_class (op_alt, i);

	    if (REG_P (op)
		&& REGNO (op) == ORIGINAL_REGNO (op))
	      continue;

	    return cl;
	  }
    }
  else if (!CALL_P (insn))
    {
      for (i = 0; i < n_ops + recog_data.n_dups; i++)
       {
	 int opn = i < n_ops ? i : recog_data.dup_num[i - n_ops];
	 enum reg_class cl = alternative_class (op_alt, opn);

	 if (recog_data.operand_type[opn] == OP_OUT ||
	     recog_data.operand_type[opn] == OP_INOUT)
	   return cl;
       }
    }

/*  Insns like
    (insn (set (reg:CCZ 17 flags) (compare:CCZ ...)))
    may result in returning NO_REGS, cause flags is written implicitly through
    CMP insn, which has no OP_OUT | OP_INOUT operands.  */
  return NO_REGS;
}

/* Calculate HARD_REGNO_RENAME_OK data for REGNO.  */
static void
init_hard_regno_rename (int regno)
{
  int cur_reg;

  SET_HARD_REG_BIT (sel_hrd.regs_for_rename[regno], regno);

  for (cur_reg = 0; cur_reg < FIRST_PSEUDO_REGISTER; cur_reg++)
    {
      /* We are not interested in renaming in other regs.  */
      if (!TEST_HARD_REG_BIT (sel_hrd.regs_ever_used, cur_reg))
        continue;

      if (HARD_REGNO_RENAME_OK (regno, cur_reg))
        SET_HARD_REG_BIT (sel_hrd.regs_for_rename[regno], cur_reg);
    }
}

/* A wrapper around HARD_REGNO_RENAME_OK that will look into the hard regs
   data first.  */
static inline bool
sel_hard_regno_rename_ok (int from ATTRIBUTE_UNUSED, int to ATTRIBUTE_UNUSED)
{
  /* Check whether this is all calculated.  */
  if (TEST_HARD_REG_BIT (sel_hrd.regs_for_rename[from], from))
    return TEST_HARD_REG_BIT (sel_hrd.regs_for_rename[from], to);

  init_hard_regno_rename (from);

  return TEST_HARD_REG_BIT (sel_hrd.regs_for_rename[from], to);
}

/* Calculate set of registers that are capable of holding MODE.  */
static void
init_regs_for_mode (machine_mode mode)
{
  int cur_reg;

  CLEAR_HARD_REG_SET (sel_hrd.regs_for_mode[mode]);
  CLEAR_HARD_REG_SET (sel_hrd.regs_for_call_clobbered[mode]);

  for (cur_reg = 0; cur_reg < FIRST_PSEUDO_REGISTER; cur_reg++)
    {
      int nregs;
      int i;

      /* See whether it accepts all modes that occur in
         original insns.  */
      if (!targetm.hard_regno_mode_ok (cur_reg, mode))
        continue;

      nregs = hard_regno_nregs (cur_reg, mode);

      for (i = nregs - 1; i >= 0; --i)
        if (fixed_regs[cur_reg + i]
                || global_regs[cur_reg + i]
            /* Can't use regs which aren't saved by
               the prologue.  */
            || !TEST_HARD_REG_BIT (sel_hrd.regs_ever_used, cur_reg + i)
	    /* Can't use regs with non-null REG_BASE_VALUE, because adjusting
	       it affects aliasing globally and invalidates all AV sets.  */
	    || get_reg_base_value (cur_reg + i)
#ifdef LEAF_REGISTERS
            /* We can't use a non-leaf register if we're in a
               leaf function.  */
            || (crtl->is_leaf
                && !LEAF_REGISTERS[cur_reg + i])
#endif
            )
          break;

      if (i >= 0)
        continue;

      if (targetm.hard_regno_call_part_clobbered (cur_reg, mode))
        SET_HARD_REG_BIT (sel_hrd.regs_for_call_clobbered[mode],
                          cur_reg);

      /* If the CUR_REG passed all the checks above,
         then it's ok.  */
      SET_HARD_REG_BIT (sel_hrd.regs_for_mode[mode], cur_reg);
    }

  sel_hrd.regs_for_mode_ok[mode] = true;
}

/* Init all register sets gathered in HRD.  */
static void
init_hard_regs_data (void)
{
  int cur_reg = 0;
  int cur_mode = 0;

  CLEAR_HARD_REG_SET (sel_hrd.regs_ever_used);
  for (cur_reg = 0; cur_reg < FIRST_PSEUDO_REGISTER; cur_reg++)
    if (df_regs_ever_live_p (cur_reg) || call_used_regs[cur_reg])
      SET_HARD_REG_BIT (sel_hrd.regs_ever_used, cur_reg);

  /* Initialize registers that are valid based on mode when this is
     really needed.  */
  for (cur_mode = 0; cur_mode < NUM_MACHINE_MODES; cur_mode++)
    sel_hrd.regs_for_mode_ok[cur_mode] = false;

  /* Mark that all HARD_REGNO_RENAME_OK is not calculated.  */
  for (cur_reg = 0; cur_reg < FIRST_PSEUDO_REGISTER; cur_reg++)
    CLEAR_HARD_REG_SET (sel_hrd.regs_for_rename[cur_reg]);

#ifdef STACK_REGS
  CLEAR_HARD_REG_SET (sel_hrd.stack_regs);

  for (cur_reg = FIRST_STACK_REG; cur_reg <= LAST_STACK_REG; cur_reg++)
    SET_HARD_REG_BIT (sel_hrd.stack_regs, cur_reg);
#endif
}

/* Mark hardware regs in REG_RENAME_P that are not suitable
   for renaming rhs in INSN due to hardware restrictions (register class,
   modes compatibility etc).  This doesn't affect original insn's dest reg,
   if it isn't in USED_REGS.  DEF is a definition insn of rhs for which the
   destination register is sought.  LHS (DEF->ORIG_INSN) may be REG or MEM.
   Registers that are in used_regs are always marked in
   unavailable_hard_regs as well.  */

static void
mark_unavailable_hard_regs (def_t def, struct reg_rename *reg_rename_p,
                            regset used_regs ATTRIBUTE_UNUSED)
{
  machine_mode mode;
  enum reg_class cl = NO_REGS;
  rtx orig_dest;
  unsigned cur_reg, regno;
  hard_reg_set_iterator hrsi;

  gcc_assert (GET_CODE (PATTERN (def->orig_insn)) == SET);
  gcc_assert (reg_rename_p);

  orig_dest = SET_DEST (PATTERN (def->orig_insn));

  /* We have decided not to rename 'mem = something;' insns, as 'something'
     is usually a register.  */
  if (!REG_P (orig_dest))
    return;

  regno = REGNO (orig_dest);

  /* If before reload, don't try to work with pseudos.  */
  if (!reload_completed && !HARD_REGISTER_NUM_P (regno))
    return;

  if (reload_completed)
    cl = get_reg_class (def->orig_insn);

  /* Stop if the original register is one of the fixed_regs, global_regs or
     frame pointer, or we could not discover its class.  */
  if (fixed_regs[regno]
      || global_regs[regno]
      || (!HARD_FRAME_POINTER_IS_FRAME_POINTER && frame_pointer_needed
	  && regno == HARD_FRAME_POINTER_REGNUM)
      || (HARD_FRAME_POINTER_IS_FRAME_POINTER && frame_pointer_needed
	  && regno == FRAME_POINTER_REGNUM)
      || (reload_completed && cl == NO_REGS))
    {
      SET_HARD_REG_SET (reg_rename_p->unavailable_hard_regs);

      /* Give a chance for original register, if it isn't in used_regs.  */
      if (!def->crosses_call)
        CLEAR_HARD_REG_BIT (reg_rename_p->unavailable_hard_regs, regno);

      return;
    }

  /* If something allocated on stack in this function, mark frame pointer
     register unavailable, considering also modes.
     FIXME: it is enough to do this once per all original defs.  */
  if (frame_pointer_needed)
    {
      add_to_hard_reg_set (&reg_rename_p->unavailable_hard_regs,
			   Pmode, FRAME_POINTER_REGNUM);

      if (!HARD_FRAME_POINTER_IS_FRAME_POINTER)
        add_to_hard_reg_set (&reg_rename_p->unavailable_hard_regs, 
			     Pmode, HARD_FRAME_POINTER_REGNUM);
    }

#ifdef STACK_REGS
  /* For the stack registers the presence of FIRST_STACK_REG in USED_REGS
     is equivalent to as if all stack regs were in this set.
     I.e. no stack register can be renamed, and even if it's an original
     register here we make sure it won't be lifted over it's previous def
     (it's previous def will appear as if it's a FIRST_STACK_REG def.
     The HARD_REGNO_RENAME_OK covers other cases in condition below.  */
  if (IN_RANGE (REGNO (orig_dest), FIRST_STACK_REG, LAST_STACK_REG)
      && REGNO_REG_SET_P (used_regs, FIRST_STACK_REG))
    IOR_HARD_REG_SET (reg_rename_p->unavailable_hard_regs,
                      sel_hrd.stack_regs);
#endif

  /* If there's a call on this path, make regs from call_used_reg_set
     unavailable.  */
  if (def->crosses_call)
    IOR_HARD_REG_SET (reg_rename_p->unavailable_hard_regs,
                      call_used_reg_set);

  /* Stop here before reload: we need FRAME_REGS, STACK_REGS, and crosses_call,
     but not register classes.  */
  if (!reload_completed)
    return;

  /* Leave regs as 'available' only from the current
     register class.  */
  COPY_HARD_REG_SET (reg_rename_p->available_for_renaming,
                     reg_class_contents[cl]);

  mode = GET_MODE (orig_dest);

  /* Leave only registers available for this mode.  */
  if (!sel_hrd.regs_for_mode_ok[mode])
    init_regs_for_mode (mode);
  AND_HARD_REG_SET (reg_rename_p->available_for_renaming,
                    sel_hrd.regs_for_mode[mode]);

  /* Exclude registers that are partially call clobbered.  */
  if (def->crosses_call
      && !targetm.hard_regno_call_part_clobbered (regno, mode))
    AND_COMPL_HARD_REG_SET (reg_rename_p->available_for_renaming,
                            sel_hrd.regs_for_call_clobbered[mode]);

  /* Leave only those that are ok to rename.  */
  EXECUTE_IF_SET_IN_HARD_REG_SET (reg_rename_p->available_for_renaming,
                                  0, cur_reg, hrsi)
    {
      int nregs;
      int i;

      nregs = hard_regno_nregs (cur_reg, mode);
      gcc_assert (nregs > 0);

      for (i = nregs - 1; i >= 0; --i)
        if (! sel_hard_regno_rename_ok (regno + i, cur_reg + i))
          break;

      if (i >= 0)
        CLEAR_HARD_REG_BIT (reg_rename_p->available_for_renaming,
                            cur_reg);
    }

  AND_COMPL_HARD_REG_SET (reg_rename_p->available_for_renaming,
                          reg_rename_p->unavailable_hard_regs);

  /* Regno is always ok from the renaming part of view, but it really
     could be in *unavailable_hard_regs already, so set it here instead
     of there.  */
  SET_HARD_REG_BIT (reg_rename_p->available_for_renaming, regno);
}

/* reg_rename_tick[REG1] > reg_rename_tick[REG2] if REG1 was chosen as the
   best register more recently than REG2.  */
static int reg_rename_tick[FIRST_PSEUDO_REGISTER];

/* Indicates the number of times renaming happened before the current one.  */
static int reg_rename_this_tick;

/* Choose the register among free, that is suitable for storing
   the rhs value.

   ORIGINAL_INSNS is the list of insns where the operation (rhs)
   originally appears.  There could be multiple original operations
   for single rhs since we moving it up and merging along different
   paths.

   Some code is adapted from regrename.c (regrename_optimize).
   If original register is available, function returns it.
   Otherwise it performs the checks, so the new register should
   comply with the following:
    - it should not violate any live ranges (such registers are in
      REG_RENAME_P->available_for_renaming set);
    - it should not be in the HARD_REGS_USED regset;
    - it should be in the class compatible with original uses;
    - it should not be clobbered through reference with different mode;
    - if we're in the leaf function, then the new register should
      not be in the LEAF_REGISTERS;
    - etc.

   If several registers meet the conditions, the register with smallest
   tick is returned to achieve more even register allocation.

   If original register seems to be ok, we set *IS_ORIG_REG_P_PTR to true.

   If no register satisfies the above conditions, NULL_RTX is returned.  */
static rtx
choose_best_reg_1 (HARD_REG_SET hard_regs_used,
                   struct reg_rename *reg_rename_p,
                   def_list_t original_insns, bool *is_orig_reg_p_ptr)
{
  int best_new_reg;
  unsigned cur_reg;
  machine_mode mode = VOIDmode;
  unsigned regno, i, n;
  hard_reg_set_iterator hrsi;
  def_list_iterator di;
  def_t def;

  /* If original register is available, return it.  */
  *is_orig_reg_p_ptr = true;

  FOR_EACH_DEF (def, di, original_insns)
    {
      rtx orig_dest = SET_DEST (PATTERN (def->orig_insn));

      gcc_assert (REG_P (orig_dest));

      /* Check that all original operations have the same mode.
         This is done for the next loop; if we'd return from this
         loop, we'd check only part of them, but in this case
         it doesn't matter.  */
      if (mode == VOIDmode)
        mode = GET_MODE (orig_dest);
      gcc_assert (mode == GET_MODE (orig_dest));

      regno = REGNO (orig_dest);
      for (i = 0, n = REG_NREGS (orig_dest); i < n; i++)
        if (TEST_HARD_REG_BIT (hard_regs_used, regno + i))
          break;

      /* All hard registers are available.  */
      if (i == n)
        {
          gcc_assert (mode != VOIDmode);

          /* Hard registers should not be shared.  */
          return gen_rtx_REG (mode, regno);
        }
    }

  *is_orig_reg_p_ptr = false;
  best_new_reg = -1;

  /* Among all available regs choose the register that was
     allocated earliest.  */
  EXECUTE_IF_SET_IN_HARD_REG_SET (reg_rename_p->available_for_renaming,
                                  0, cur_reg, hrsi)
    if (! TEST_HARD_REG_BIT (hard_regs_used, cur_reg))
      {
	/* Check that all hard regs for mode are available.  */
	for (i = 1, n = hard_regno_nregs (cur_reg, mode); i < n; i++)
	  if (TEST_HARD_REG_BIT (hard_regs_used, cur_reg + i)
	      || !TEST_HARD_REG_BIT (reg_rename_p->available_for_renaming,
				     cur_reg + i))
	    break;

	if (i < n)
	  continue;

        /* All hard registers are available.  */
        if (best_new_reg < 0
            || reg_rename_tick[cur_reg] < reg_rename_tick[best_new_reg])
          {
            best_new_reg = cur_reg;

            /* Return immediately when we know there's no better reg.  */
            if (! reg_rename_tick[best_new_reg])
              break;
          }
      }

  if (best_new_reg >= 0)
    {
      /* Use the check from the above loop.  */
      gcc_assert (mode != VOIDmode);
      return gen_rtx_REG (mode, best_new_reg);
    }

  return NULL_RTX;
}

/* A wrapper around choose_best_reg_1 () to verify that we make correct
   assumptions about available registers in the function.  */
static rtx
choose_best_reg (HARD_REG_SET hard_regs_used, struct reg_rename *reg_rename_p,
                 def_list_t original_insns, bool *is_orig_reg_p_ptr)
{
  rtx best_reg = choose_best_reg_1 (hard_regs_used, reg_rename_p,
                                    original_insns, is_orig_reg_p_ptr);

  /* FIXME loop over hard_regno_nregs here.  */
  gcc_assert (best_reg == NULL_RTX
	      || TEST_HARD_REG_BIT (sel_hrd.regs_ever_used, REGNO (best_reg)));

  return best_reg;
}

/* Choose the pseudo register for storing rhs value.  As this is supposed
   to work before reload, we return either the original register or make
   the new one.  The parameters are the same that in choose_nest_reg_1
   functions, except that USED_REGS may contain pseudos.
   If we work with hard regs, check also REG_RENAME_P->UNAVAILABLE_HARD_REGS.

   TODO: take into account register pressure while doing this.  Up to this
   moment, this function would never return NULL for pseudos, but we should
   not rely on this.  */
static rtx
choose_best_pseudo_reg (regset used_regs,
                        struct reg_rename *reg_rename_p,
                        def_list_t original_insns, bool *is_orig_reg_p_ptr)
{
  def_list_iterator i;
  def_t def;
  machine_mode mode = VOIDmode;
  bool bad_hard_regs = false;

  /* We should not use this after reload.  */
  gcc_assert (!reload_completed);

  /* If original register is available, return it.  */
  *is_orig_reg_p_ptr = true;

  FOR_EACH_DEF (def, i, original_insns)
    {
      rtx dest = SET_DEST (PATTERN (def->orig_insn));
      int orig_regno;

      gcc_assert (REG_P (dest));

      /* Check that all original operations have the same mode.  */
      if (mode == VOIDmode)
        mode = GET_MODE (dest);
      else
        gcc_assert (mode == GET_MODE (dest));
      orig_regno = REGNO (dest);

      /* Check that nothing in used_regs intersects with orig_regno.  When
	 we have a hard reg here, still loop over hard_regno_nregs.  */
      if (HARD_REGISTER_NUM_P (orig_regno))
	{
	  int j, n;
	  for (j = 0, n = REG_NREGS (dest); j < n; j++)
	    if (REGNO_REG_SET_P (used_regs, orig_regno + j))
	      break;
	  if (j < n)
	    continue;
	}
      else
	{
	  if (REGNO_REG_SET_P (used_regs, orig_regno))
	    continue;
	}
      if (HARD_REGISTER_NUM_P (orig_regno))
	{
	  gcc_assert (df_regs_ever_live_p (orig_regno));

	  /* For hard registers, we have to check hardware imposed
	     limitations (frame/stack registers, calls crossed).  */
	  if (!TEST_HARD_REG_BIT (reg_rename_p->unavailable_hard_regs,
				  orig_regno))
	    {
	      /* Don't let register cross a call if it doesn't already
		 cross one.  This condition is written in accordance with
		 that in sched-deps.c sched_analyze_reg().  */
	      if (!reg_rename_p->crosses_call
		  || REG_N_CALLS_CROSSED (orig_regno) > 0)
		return gen_rtx_REG (mode, orig_regno);
	    }

	  bad_hard_regs = true;
	}
      else
	return dest;
    }

  *is_orig_reg_p_ptr = false;

  /* We had some original hard registers that couldn't be used.
     Those were likely special.  Don't try to create a pseudo.  */
  if (bad_hard_regs)
    return NULL_RTX;

  /* We haven't found a register from original operations.  Get a new one.
     FIXME: control register pressure somehow.  */
  {
    rtx new_reg = gen_reg_rtx (mode);

    gcc_assert (mode != VOIDmode);

    max_regno = max_reg_num ();
    maybe_extend_reg_info_p ();
    REG_N_CALLS_CROSSED (REGNO (new_reg)) = reg_rename_p->crosses_call ? 1 : 0;

    return new_reg;
  }
}

/* True when target of EXPR is available due to EXPR_TARGET_AVAILABLE,
   USED_REGS and REG_RENAME_P->UNAVAILABLE_HARD_REGS.  */
static void
verify_target_availability (expr_t expr, regset used_regs,
			    struct reg_rename *reg_rename_p)
{
  unsigned n, i, regno;
  machine_mode mode;
  bool target_available, live_available, hard_available;

  if (!REG_P (EXPR_LHS (expr)) || EXPR_TARGET_AVAILABLE (expr) < 0)
    return;

  regno = expr_dest_regno (expr);
  mode = GET_MODE (EXPR_LHS (expr));
  target_available = EXPR_TARGET_AVAILABLE (expr) == 1;
  n = HARD_REGISTER_NUM_P (regno) ? hard_regno_nregs (regno, mode) : 1;

  live_available = hard_available = true;
  for (i = 0; i < n; i++)
    {
      if (bitmap_bit_p (used_regs, regno + i))
        live_available = false;
      if (TEST_HARD_REG_BIT (reg_rename_p->unavailable_hard_regs, regno + i))
        hard_available = false;
    }

  /* When target is not available, it may be due to hard register
     restrictions, e.g. crosses calls, so we check hard_available too.  */
  if (target_available)
    gcc_assert (live_available);
  else
    /* Check only if we haven't scheduled something on the previous fence,
       cause due to MAX_SOFTWARE_LOOKAHEAD_WINDOW_SIZE issues
       and having more than one fence, we may end having targ_un in a block
       in which successors target register is actually available.

       The last condition handles the case when a dependence from a call insn
       was created in sched-deps.c for insns with destination registers that
       never crossed a call before, but do cross one after our code motion.

       FIXME: in the latter case, we just uselessly called find_used_regs,
       because we can't move this expression with any other register
       as well.  */
    gcc_assert (scheduled_something_on_previous_fence || !live_available
		|| !hard_available
		|| (!reload_completed && reg_rename_p->crosses_call
		    && REG_N_CALLS_CROSSED (regno) == 0));
}

/* Collect unavailable registers due to liveness for EXPR from BNDS
   into USED_REGS.  Save additional information about available
   registers and unavailable due to hardware restriction registers
   into REG_RENAME_P structure.  Save original insns into ORIGINAL_INSNS
   list.  */
static void
collect_unavailable_regs_from_bnds (expr_t expr, blist_t bnds, regset used_regs,
				    struct reg_rename *reg_rename_p,
				    def_list_t *original_insns)
{
  for (; bnds; bnds = BLIST_NEXT (bnds))
    {
      bool res;
      av_set_t orig_ops = NULL;
      bnd_t bnd = BLIST_BND (bnds);

      /* If the chosen best expr doesn't belong to current boundary,
	 skip it.  */
      if (!av_set_is_in_p (BND_AV1 (bnd), EXPR_VINSN (expr)))
	continue;

      /* Put in ORIG_OPS all exprs from this boundary that became
	 RES on top.  */
      orig_ops = find_sequential_best_exprs (bnd, expr, false);

      /* Compute used regs and OR it into the USED_REGS.  */
      res = find_used_regs (BND_TO (bnd), orig_ops, used_regs,
			    reg_rename_p, original_insns);

      /* FIXME: the assert is true until we'd have several boundaries.  */
      gcc_assert (res);
      av_set_clear (&orig_ops);
    }
}

/* Return TRUE if it is possible to replace LHSes of ORIG_INSNS with BEST_REG.
   If BEST_REG is valid, replace LHS of EXPR with it.  */
static bool
try_replace_dest_reg (ilist_t orig_insns, rtx best_reg, expr_t expr)
{
  /* Try whether we'll be able to generate the insn
     'dest := best_reg' at the place of the original operation.  */
  for (; orig_insns; orig_insns = ILIST_NEXT (orig_insns))
    {
      insn_t orig_insn = DEF_LIST_DEF (orig_insns)->orig_insn;

      gcc_assert (EXPR_SEPARABLE_P (INSN_EXPR (orig_insn)));

      if (REGNO (best_reg) != REGNO (INSN_LHS (orig_insn))
	  && (! replace_src_with_reg_ok_p (orig_insn, best_reg)
	      || ! replace_dest_with_reg_ok_p (orig_insn, best_reg)))
	return false;
    }

  /* Make sure that EXPR has the right destination
     register.  */
  if (expr_dest_regno (expr) != REGNO (best_reg))
    replace_dest_with_reg_in_expr (expr, best_reg);
  else
    EXPR_TARGET_AVAILABLE (expr) = 1;

  return true;
}

/* Select and assign best register to EXPR searching from BNDS.
   Set *IS_ORIG_REG_P to TRUE if original register was selected.
   Return FALSE if no register can be chosen, which could happen when:
   * EXPR_SEPARABLE_P is true but we were unable to find suitable register;
   * EXPR_SEPARABLE_P is false but the insn sets/clobbers one of the registers
     that are used on the moving path.  */
static bool
find_best_reg_for_expr (expr_t expr, blist_t bnds, bool *is_orig_reg_p)
{
  static struct reg_rename reg_rename_data;

  regset used_regs;
  def_list_t original_insns = NULL;
  bool reg_ok;

  *is_orig_reg_p = false;

  /* Don't bother to do anything if this insn doesn't set any registers.  */
  if (bitmap_empty_p (VINSN_REG_SETS (EXPR_VINSN (expr)))
      && bitmap_empty_p (VINSN_REG_CLOBBERS (EXPR_VINSN (expr))))
    return true;

  used_regs = get_clear_regset_from_pool ();
  CLEAR_HARD_REG_SET (reg_rename_data.unavailable_hard_regs);

  collect_unavailable_regs_from_bnds (expr, bnds, used_regs, &reg_rename_data,
				      &original_insns);

  /* If after reload, make sure we're working with hard regs here.  */
  if (flag_checking && reload_completed)
    {
      reg_set_iterator rsi;
      unsigned i;

      EXECUTE_IF_SET_IN_REG_SET (used_regs, FIRST_PSEUDO_REGISTER, i, rsi)
        gcc_unreachable ();
    }

  if (EXPR_SEPARABLE_P (expr))
    {
      rtx best_reg = NULL_RTX;
      /* Check that we have computed availability of a target register
	 correctly.  */
      verify_target_availability (expr, used_regs, &reg_rename_data);

      /* Turn everything in hard regs after reload.  */
      if (reload_completed)
	{
	  HARD_REG_SET hard_regs_used;
	  REG_SET_TO_HARD_REG_SET (hard_regs_used, used_regs);

	  /* Join hard registers unavailable due to register class
	     restrictions and live range intersection.  */
	  IOR_HARD_REG_SET (hard_regs_used,
			    reg_rename_data.unavailable_hard_regs);

	  best_reg = choose_best_reg (hard_regs_used, &reg_rename_data,
				      original_insns, is_orig_reg_p);
	}
      else
	best_reg = choose_best_pseudo_reg (used_regs, &reg_rename_data,
					   original_insns, is_orig_reg_p);

      if (!best_reg)
	reg_ok = false;
      else if (*is_orig_reg_p)
	{
	  /* In case of unification BEST_REG may be different from EXPR's LHS
	     when EXPR's LHS is unavailable, and there is another LHS among
	     ORIGINAL_INSNS.  */
	  reg_ok = try_replace_dest_reg (original_insns, best_reg, expr);
	}
      else
	{
	  /* Forbid renaming of low-cost insns.  */
	  if (sel_vinsn_cost (EXPR_VINSN (expr)) < 2)
	    reg_ok = false;
	  else
	    reg_ok = try_replace_dest_reg (original_insns, best_reg, expr);
	}
    }
  else
    {
      /* If !EXPR_SCHEDULE_AS_RHS (EXPR), just make sure INSN doesn't set
	 any of the HARD_REGS_USED set.  */
      if (vinsn_writes_one_of_regs_p (EXPR_VINSN (expr), used_regs,
				      reg_rename_data.unavailable_hard_regs))
	{
	  reg_ok = false;
	  gcc_assert (EXPR_TARGET_AVAILABLE (expr) <= 0);
	}
      else
	{
	  reg_ok = true;
	  gcc_assert (EXPR_TARGET_AVAILABLE (expr) != 0);
	}
    }

  ilist_clear (&original_insns);
  return_regset_to_pool (used_regs);

  return reg_ok;
}


/* Return true if dependence described by DS can be overcomed.  */
static bool
can_speculate_dep_p (ds_t ds)
{
  if (spec_info == NULL)
    return false;

  /* Leave only speculative data.  */
  ds &= SPECULATIVE;

  if (ds == 0)
    return false;

  {
    /* FIXME: make sched-deps.c produce only those non-hard dependencies,
       that we can overcome.  */
    ds_t spec_mask = spec_info->mask;

    if ((ds & spec_mask) != ds)
      return false;
  }

  if (ds_weak (ds) < spec_info->data_weakness_cutoff)
    return false;

  return true;
}

/* Get a speculation check instruction.
   C_EXPR is a speculative expression,
   CHECK_DS describes speculations that should be checked,
   ORIG_INSN is the original non-speculative insn in the stream.  */
static insn_t
create_speculation_check (expr_t c_expr, ds_t check_ds, insn_t orig_insn)
{
  rtx check_pattern;
  rtx_insn *insn_rtx;
  insn_t insn;
  basic_block recovery_block;
  rtx_insn *label;

  /* Create a recovery block if target is going to emit branchy check, or if
     ORIG_INSN was speculative already.  */
  if (targetm.sched.needs_block_p (check_ds)
      || EXPR_SPEC_DONE_DS (INSN_EXPR (orig_insn)) != 0)
    {
      recovery_block = sel_create_recovery_block (orig_insn);
      label = BB_HEAD (recovery_block);
    }
  else
    {
      recovery_block = NULL;
      label = NULL;
    }

  /* Get pattern of the check.  */
  check_pattern = targetm.sched.gen_spec_check (EXPR_INSN_RTX (c_expr), label,
						check_ds);

  gcc_assert (check_pattern != NULL);

  /* Emit check.  */
  insn_rtx = create_insn_rtx_from_pattern (check_pattern, label);

  insn = sel_gen_insn_from_rtx_after (insn_rtx, INSN_EXPR (orig_insn),
				      INSN_SEQNO (orig_insn), orig_insn);

  /* Make check to be non-speculative.  */
  EXPR_SPEC_DONE_DS (INSN_EXPR (insn)) = 0;
  INSN_SPEC_CHECKED_DS (insn) = check_ds;

  /* Decrease priority of check by difference of load/check instruction
     latencies.  */
  EXPR_PRIORITY (INSN_EXPR (insn)) -= (sel_vinsn_cost (INSN_VINSN (orig_insn))
				       - sel_vinsn_cost (INSN_VINSN (insn)));

  /* Emit copy of original insn (though with replaced target register,
     if needed) to the recovery block.  */
  if (recovery_block != NULL)
    {
      rtx twin_rtx;

      twin_rtx = copy_rtx (PATTERN (EXPR_INSN_RTX (c_expr)));
      twin_rtx = create_insn_rtx_from_pattern (twin_rtx, NULL_RTX);
      sel_gen_recovery_insn_from_rtx_after (twin_rtx,
					    INSN_EXPR (orig_insn),
					    INSN_SEQNO (insn),
					    bb_note (recovery_block));
    }

  /* If we've generated a data speculation check, make sure
     that all the bookkeeping instruction we'll create during
     this move_op () will allocate an ALAT entry so that the
     check won't fail.
     In case of control speculation we must convert C_EXPR to control
     speculative mode, because failing to do so will bring us an exception
     thrown by the non-control-speculative load.  */
  check_ds = ds_get_max_dep_weak (check_ds);
  speculate_expr (c_expr, check_ds);

  return insn;
}

/* True when INSN is a "regN = regN" copy.  */
static bool
identical_copy_p (rtx_insn *insn)
{
  rtx lhs, rhs, pat;

  pat = PATTERN (insn);

  if (GET_CODE (pat) != SET)
    return false;

  lhs = SET_DEST (pat);
  if (!REG_P (lhs))
    return false;

  rhs = SET_SRC (pat);
  if (!REG_P (rhs))
    return false;

  return REGNO (lhs) == REGNO (rhs);
}

/* Undo all transformations on *AV_PTR that were done when
   moving through INSN.  */
static void
undo_transformations (av_set_t *av_ptr, rtx_insn *insn)
{
  av_set_iterator av_iter;
  expr_t expr;
  av_set_t new_set = NULL;

  /* First, kill any EXPR that uses registers set by an insn.  This is
     required for correctness.  */
  FOR_EACH_EXPR_1 (expr, av_iter, av_ptr)
    if (!sched_insns_conditions_mutex_p (insn, EXPR_INSN_RTX (expr))
        && bitmap_intersect_p (INSN_REG_SETS (insn),
                               VINSN_REG_USES (EXPR_VINSN (expr)))
        /* When an insn looks like 'r1 = r1', we could substitute through
           it, but the above condition will still hold.  This happened with
           gcc.c-torture/execute/961125-1.c.  */
        && !identical_copy_p (insn))
      {
        if (sched_verbose >= 6)
          sel_print ("Expr %d removed due to use/set conflict\n",
                     INSN_UID (EXPR_INSN_RTX (expr)));
        av_set_iter_remove (&av_iter);
      }

  /* Undo transformations looking at the history vector.  */
  FOR_EACH_EXPR (expr, av_iter, *av_ptr)
    {
      int index = find_in_history_vect (EXPR_HISTORY_OF_CHANGES (expr),
                                        insn, EXPR_VINSN (expr), true);

      if (index >= 0)
        {
          expr_history_def *phist;

          phist = &EXPR_HISTORY_OF_CHANGES (expr)[index];

          switch (phist->type)
            {
            case TRANS_SPECULATION:
              {
                ds_t old_ds, new_ds;

                /* Compute the difference between old and new speculative
                   statuses: that's what we need to check.
                   Earlier we used to assert that the status will really
                   change.  This no longer works because only the probability
                   bits in the status may have changed during compute_av_set,
                   and in the case of merging different probabilities of the
                   same speculative status along different paths we do not
                   record this in the history vector.  */
                old_ds = phist->spec_ds;
                new_ds = EXPR_SPEC_DONE_DS (expr);

                old_ds &= SPECULATIVE;
                new_ds &= SPECULATIVE;
                new_ds &= ~old_ds;

                EXPR_SPEC_TO_CHECK_DS (expr) |= new_ds;
                break;
              }
            case TRANS_SUBSTITUTION:
              {
                expr_def _tmp_expr, *tmp_expr = &_tmp_expr;
                vinsn_t new_vi;
                bool add = true;

                new_vi = phist->old_expr_vinsn;

                gcc_assert (VINSN_SEPARABLE_P (new_vi)
                            == EXPR_SEPARABLE_P (expr));
                copy_expr (tmp_expr, expr);

                if (vinsn_equal_p (phist->new_expr_vinsn,
                                   EXPR_VINSN (tmp_expr)))
                  change_vinsn_in_expr (tmp_expr, new_vi);
                else
                  /* This happens when we're unsubstituting on a bookkeeping
                     copy, which was in turn substituted.  The history is wrong
                     in this case.  Do it the hard way.  */
                  add = substitute_reg_in_expr (tmp_expr, insn, true);
                if (add)
                  av_set_add (&new_set, tmp_expr);
                clear_expr (tmp_expr);
                break;
              }
            default:
              gcc_unreachable ();
            }
        }

    }

  av_set_union_and_clear (av_ptr, &new_set, NULL);
}


/* Moveup_* helpers for code motion and computing av sets.  */

/* Propagates EXPR inside an insn group through THROUGH_INSN.
   The difference from the below function is that only substitution is
   performed.  */
static enum MOVEUP_EXPR_CODE
moveup_expr_inside_insn_group (expr_t expr, insn_t through_insn)
{
  vinsn_t vi = EXPR_VINSN (expr);
  ds_t *has_dep_p;
  ds_t full_ds;

  /* Do this only inside insn group.  */
  gcc_assert (INSN_SCHED_CYCLE (through_insn) > 0);

  full_ds = has_dependence_p (expr, through_insn, &has_dep_p);
  if (full_ds == 0)
    return MOVEUP_EXPR_SAME;

  /* Substitution is the possible choice in this case.  */
  if (has_dep_p[DEPS_IN_RHS])
    {
      /* Can't substitute UNIQUE VINSNs.  */
      gcc_assert (!VINSN_UNIQUE_P (vi));

      if (can_substitute_through_p (through_insn,
                                    has_dep_p[DEPS_IN_RHS])
          && substitute_reg_in_expr (expr, through_insn, false))
        {
          EXPR_WAS_SUBSTITUTED (expr) = true;
          return MOVEUP_EXPR_CHANGED;
        }

      /* Don't care about this, as even true dependencies may be allowed
         in an insn group.  */
      return MOVEUP_EXPR_SAME;
    }

  /* This can catch output dependencies in COND_EXECs.  */
  if (has_dep_p[DEPS_IN_INSN])
    return MOVEUP_EXPR_NULL;

  /* This is either an output or an anti dependence, which usually have
     a zero latency.  Allow this here, if we'd be wrong, tick_check_p
     will fix this.  */
  gcc_assert (has_dep_p[DEPS_IN_LHS]);
  return MOVEUP_EXPR_AS_RHS;
}

/* True when a trapping EXPR cannot be moved through THROUGH_INSN.  */
#define CANT_MOVE_TRAPPING(expr, through_insn)                \
  (VINSN_MAY_TRAP_P (EXPR_VINSN (expr))                       \
   && !sel_insn_has_single_succ_p ((through_insn), SUCCS_ALL) \
   && !sel_insn_is_speculation_check (through_insn))

/* True when a conflict on a target register was found during moveup_expr.  */
static bool was_target_conflict = false;

/* Return true when moving a debug INSN across THROUGH_INSN will
   create a bookkeeping block.  We don't want to create such blocks,
   for they would cause codegen differences between compilations with
   and without debug info.  */

static bool
moving_insn_creates_bookkeeping_block_p (insn_t insn,
					 insn_t through_insn)
{
  basic_block bbi, bbt;
  edge e1, e2;
  edge_iterator ei1, ei2;

  if (!bookkeeping_can_be_created_if_moved_through_p (through_insn))
    {
      if (sched_verbose >= 9)
	sel_print ("no bookkeeping required: ");
      return FALSE;
    }

  bbi = BLOCK_FOR_INSN (insn);

  if (EDGE_COUNT (bbi->preds) == 1)
    {
      if (sched_verbose >= 9)
	sel_print ("only one pred edge: ");
      return TRUE;
    }

  bbt = BLOCK_FOR_INSN (through_insn);

  FOR_EACH_EDGE (e1, ei1, bbt->succs)
    {
      FOR_EACH_EDGE (e2, ei2, bbi->preds)
	{
	  if (find_block_for_bookkeeping (e1, e2, TRUE))
	    {
	      if (sched_verbose >= 9)
		sel_print ("found existing block: ");
	      return FALSE;
	    }
	}
    }

  if (sched_verbose >= 9)
    sel_print ("would create bookkeeping block: ");

  return TRUE;
}

/* Return true when the conflict with newly created implicit clobbers
   between EXPR and THROUGH_INSN is found because of renaming.  */
static bool
implicit_clobber_conflict_p (insn_t through_insn, expr_t expr)
{
  HARD_REG_SET temp;
  rtx_insn *insn;
  rtx reg, rhs, pat;
  hard_reg_set_iterator hrsi;
  unsigned regno;
  bool valid;

  /* Make a new pseudo register.  */
  reg = gen_reg_rtx (GET_MODE (EXPR_LHS (expr)));
  max_regno = max_reg_num ();
  maybe_extend_reg_info_p ();

  /* Validate a change and bail out early.  */
  insn = EXPR_INSN_RTX (expr);
  validate_change (insn, &SET_DEST (PATTERN (insn)), reg, true);
  valid = verify_changes (0);
  cancel_changes (0);
  if (!valid)
    {
      if (sched_verbose >= 6)
	sel_print ("implicit clobbers failed validation, ");
      return true;
    }

  /* Make a new insn with it.  */
  rhs = copy_rtx (VINSN_RHS (EXPR_VINSN (expr)));
  pat = gen_rtx_SET (reg, rhs);
  start_sequence ();
  insn = emit_insn (pat);
  end_sequence ();

  /* Calculate implicit clobbers.  */
  extract_insn (insn);
  preprocess_constraints (insn);
  alternative_mask prefrred = get_preferred_alternatives (insn);
  ira_implicitly_set_insn_hard_regs (&temp, prefrred);
  AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs);

  /* If any implicit clobber registers intersect with regular ones in
     through_insn, we have a dependency and thus bail out.  */
  EXECUTE_IF_SET_IN_HARD_REG_SET (temp, 0, regno, hrsi)
    {
      vinsn_t vi = INSN_VINSN (through_insn);
      if (bitmap_bit_p (VINSN_REG_SETS (vi), regno)
	  || bitmap_bit_p (VINSN_REG_CLOBBERS (vi), regno)
	  || bitmap_bit_p (VINSN_REG_USES (vi), regno))
	return true;
    }

  return false;
}

/* Modifies EXPR so it can be moved through the THROUGH_INSN,
   performing necessary transformations.  Record the type of transformation
   made in PTRANS_TYPE, when it is not NULL.  When INSIDE_INSN_GROUP,
   permit all dependencies except true ones, and try to remove those
   too via forward substitution.  All cases when a non-eliminable
   non-zero cost dependency exists inside an insn group will be fixed
   in tick_check_p instead.  */
static enum MOVEUP_EXPR_CODE
moveup_expr (expr_t expr, insn_t through_insn, bool inside_insn_group,
            enum local_trans_type *ptrans_type)
{
  vinsn_t vi = EXPR_VINSN (expr);
  insn_t insn = VINSN_INSN_RTX (vi);
  bool was_changed = false;
  bool as_rhs = false;
  ds_t *has_dep_p;
  ds_t full_ds;

  /* ??? We use dependencies of non-debug insns on debug insns to
     indicate that the debug insns need to be reset if the non-debug
     insn is pulled ahead of it.  It's hard to figure out how to
     introduce such a notion in sel-sched, but it already fails to
     support debug insns in other ways, so we just go ahead and
     let the deug insns go corrupt for now.  */
  if (DEBUG_INSN_P (through_insn) && !DEBUG_INSN_P (insn))
    return MOVEUP_EXPR_SAME;

  /* When inside_insn_group, delegate to the helper.  */
  if (inside_insn_group)
    return moveup_expr_inside_insn_group (expr, through_insn);

  /* Deal with unique insns and control dependencies.  */
  if (VINSN_UNIQUE_P (vi))
    {
      /* We can move jumps without side-effects or jumps that are
	 mutually exclusive with instruction THROUGH_INSN (all in cases
	 dependencies allow to do so and jump is not speculative).  */
      if (control_flow_insn_p (insn))
        {
          basic_block fallthru_bb;

          /* Do not move checks and do not move jumps through other
             jumps.  */
          if (control_flow_insn_p (through_insn)
              || sel_insn_is_speculation_check (insn))
            return MOVEUP_EXPR_NULL;

          /* Don't move jumps through CFG joins.  */
          if (bookkeeping_can_be_created_if_moved_through_p (through_insn))
            return MOVEUP_EXPR_NULL;

          /* The jump should have a clear fallthru block, and
             this block should be in the current region.  */
          if ((fallthru_bb = fallthru_bb_of_jump (insn)) == NULL
              || ! in_current_region_p (fallthru_bb))
            return MOVEUP_EXPR_NULL;

          /* And it should be mutually exclusive with through_insn.  */
          if (! sched_insns_conditions_mutex_p (insn, through_insn)
	      && ! DEBUG_INSN_P (through_insn))
            return MOVEUP_EXPR_NULL;
        }

      /* Don't move what we can't move.  */
      if (EXPR_CANT_MOVE (expr)
	  && BLOCK_FOR_INSN (through_insn) != BLOCK_FOR_INSN (insn))
	return MOVEUP_EXPR_NULL;

      /* Don't move SCHED_GROUP instruction through anything.
         If we don't force this, then it will be possible to start
         scheduling a sched_group before all its dependencies are
         resolved.
         ??? Haifa deals with this issue by delaying the SCHED_GROUP
         as late as possible through rank_for_schedule.  */
      if (SCHED_GROUP_P (insn))
	return MOVEUP_EXPR_NULL;
    }
  else
    gcc_assert (!control_flow_insn_p (insn));

  /* Don't move debug insns if this would require bookkeeping.  */
  if (DEBUG_INSN_P (insn)
      && BLOCK_FOR_INSN (through_insn) != BLOCK_FOR_INSN (insn)
      && moving_insn_creates_bookkeeping_block_p (insn, through_insn))
    return MOVEUP_EXPR_NULL;

  /* Deal with data dependencies.  */
  was_target_conflict = false;
  full_ds = has_dependence_p (expr, through_insn, &has_dep_p);
  if (full_ds == 0)
    {
      if (!CANT_MOVE_TRAPPING (expr, through_insn))
	return MOVEUP_EXPR_SAME;
    }
  else
    {
      /* We can move UNIQUE insn up only as a whole and unchanged,
         so it shouldn't have any dependencies.  */
      if (VINSN_UNIQUE_P (vi))
	return MOVEUP_EXPR_NULL;
    }

  if (full_ds != 0 && can_speculate_dep_p (full_ds))
    {
      int res;

      res = speculate_expr (expr, full_ds);
      if (res >= 0)
	{
          /* Speculation was successful.  */
          full_ds = 0;
          was_changed = (res > 0);
          if (res == 2)
            was_target_conflict = true;
          if (ptrans_type)
            *ptrans_type = TRANS_SPECULATION;
	  sel_clear_has_dependence ();
	}
    }

  if (has_dep_p[DEPS_IN_INSN])
    /* We have some dependency that cannot be discarded.  */
    return MOVEUP_EXPR_NULL;

  if (has_dep_p[DEPS_IN_LHS])
    {
      /* Only separable insns can be moved up with the new register.
         Anyways, we should mark that the original register is
         unavailable.  */
      if (!enable_schedule_as_rhs_p || !EXPR_SEPARABLE_P (expr))
        return MOVEUP_EXPR_NULL;

      /* When renaming a hard register to a pseudo before reload, extra
	 dependencies can occur from the implicit clobbers of the insn.
	 Filter out such cases here.  */
      if (!reload_completed && REG_P (EXPR_LHS (expr))
	  && HARD_REGISTER_P (EXPR_LHS (expr))
	  && implicit_clobber_conflict_p (through_insn, expr))
	{
	  if (sched_verbose >= 6)
	    sel_print ("implicit clobbers conflict detected, ");
	  return MOVEUP_EXPR_NULL;
	}
      EXPR_TARGET_AVAILABLE (expr) = false;
      was_target_conflict = true;
      as_rhs = true;
    }

  /* At this point we have either separable insns, that will be lifted
     up only as RHSes, or non-separable insns with no dependency in lhs.
     If dependency is in RHS, then try to perform substitution and move up
     substituted RHS:

      Ex. 1:				  Ex.2
	y = x;				    y = x;
	z = y*2;			    y = y*2;

    In Ex.1 y*2 can be substituted for x*2 and the whole operation can be
    moved above y=x assignment as z=x*2.

    In Ex.2 y*2 also can be substituted for x*2, but only the right hand
    side can be moved because of the output dependency.  The operation was
    cropped to its rhs above.  */
  if (has_dep_p[DEPS_IN_RHS])
    {
      ds_t *rhs_dsp = &has_dep_p[DEPS_IN_RHS];

      /* Can't substitute UNIQUE VINSNs.  */
      gcc_assert (!VINSN_UNIQUE_P (vi));

      if (can_speculate_dep_p (*rhs_dsp))
	{
          int res;

          res = speculate_expr (expr, *rhs_dsp);
          if (res >= 0)
            {
              /* Speculation was successful.  */
              *rhs_dsp = 0;
              was_changed = (res > 0);
              if (res == 2)
                was_target_conflict = true;
              if (ptrans_type)
                *ptrans_type = TRANS_SPECULATION;
            }
	  else
	    return MOVEUP_EXPR_NULL;
	}
      else if (can_substitute_through_p (through_insn,
                                         *rhs_dsp)
               && substitute_reg_in_expr (expr, through_insn, false))
	{
          /* ??? We cannot perform substitution AND speculation on the same
             insn.  */
          gcc_assert (!was_changed);
          was_changed = true;
          if (ptrans_type)
            *ptrans_type = TRANS_SUBSTITUTION;
          EXPR_WAS_SUBSTITUTED (expr) = true;
	}
      else
	return MOVEUP_EXPR_NULL;
    }

  /* Don't move trapping insns through jumps.
     This check should be at the end to give a chance to control speculation
     to perform its duties.  */
  if (CANT_MOVE_TRAPPING (expr, through_insn))
    return MOVEUP_EXPR_NULL;

  return (was_changed
          ? MOVEUP_EXPR_CHANGED
          : (as_rhs
             ? MOVEUP_EXPR_AS_RHS
             : MOVEUP_EXPR_SAME));
}

/* Try to look at bitmap caches for EXPR and INSN pair, return true
   if successful.  When INSIDE_INSN_GROUP, also try ignore dependencies
   that can exist within a parallel group.  Write to RES the resulting
   code for moveup_expr.  */
static bool
try_bitmap_cache (expr_t expr, insn_t insn,
                  bool inside_insn_group,
                  enum MOVEUP_EXPR_CODE *res)
{
  int expr_uid = INSN_UID (EXPR_INSN_RTX (expr));

  /* First check whether we've analyzed this situation already.  */
  if (bitmap_bit_p (INSN_ANALYZED_DEPS (insn), expr_uid))
    {
      if (bitmap_bit_p (INSN_FOUND_DEPS (insn), expr_uid))
        {
          if (sched_verbose >= 6)
            sel_print ("removed (cached)\n");
          *res = MOVEUP_EXPR_NULL;
          return true;
        }
      else
        {
          if (sched_verbose >= 6)
            sel_print ("unchanged (cached)\n");
          *res = MOVEUP_EXPR_SAME;
          return true;
        }
    }
  else if (bitmap_bit_p (INSN_FOUND_DEPS (insn), expr_uid))
    {
      if (inside_insn_group)
        {
          if (sched_verbose >= 6)
            sel_print ("unchanged (as RHS, cached, inside insn group)\n");
          *res = MOVEUP_EXPR_SAME;
          return true;

        }
      else
        EXPR_TARGET_AVAILABLE (expr) = false;

      /* This is the only case when propagation result can change over time,
         as we can dynamically switch off scheduling as RHS.  In this case,
         just check the flag to reach the correct decision.  */
      if (enable_schedule_as_rhs_p)
        {
          if (sched_verbose >= 6)
            sel_print ("unchanged (as RHS, cached)\n");
          *res = MOVEUP_EXPR_AS_RHS;
          return true;
        }
      else
        {
          if (sched_verbose >= 6)
            sel_print ("removed (cached as RHS, but renaming"
                       " is now disabled)\n");
          *res = MOVEUP_EXPR_NULL;
          return true;
        }
    }

  return false;
}

/* Try to look at bitmap caches for EXPR and INSN pair, return true
   if successful.  Write to RES the resulting code for moveup_expr.  */
static bool
try_transformation_cache (expr_t expr, insn_t insn,
                          enum MOVEUP_EXPR_CODE *res)
{
  struct transformed_insns *pti
    = (struct transformed_insns *)
    htab_find_with_hash (INSN_TRANSFORMED_INSNS (insn),
                         &EXPR_VINSN (expr),
                         VINSN_HASH_RTX (EXPR_VINSN (expr)));
  if (pti)
    {
      /* This EXPR was already moved through this insn and was
         changed as a result.  Fetch the proper data from
         the hashtable.  */
      insert_in_history_vect (&EXPR_HISTORY_OF_CHANGES (expr),
                              INSN_UID (insn), pti->type,
                              pti->vinsn_old, pti->vinsn_new,
                              EXPR_SPEC_DONE_DS (expr));

      if (INSN_IN_STREAM_P (VINSN_INSN_RTX (pti->vinsn_new)))
        pti->vinsn_new = vinsn_copy (pti->vinsn_new, true);
      change_vinsn_in_expr (expr, pti->vinsn_new);
      if (pti->was_target_conflict)
        EXPR_TARGET_AVAILABLE (expr) = false;
      if (pti->type == TRANS_SPECULATION)
        {
          EXPR_SPEC_DONE_DS (expr) = pti->ds;
          EXPR_NEEDS_SPEC_CHECK_P (expr) |= pti->needs_check;
        }

      if (sched_verbose >= 6)
        {
          sel_print ("changed (cached): ");
          dump_expr (expr);
          sel_print ("\n");
        }

      *res = MOVEUP_EXPR_CHANGED;
      return true;
    }

  return false;
}

/* Update bitmap caches on INSN with result RES of propagating EXPR.  */
static void
update_bitmap_cache (expr_t expr, insn_t insn, bool inside_insn_group,
                     enum MOVEUP_EXPR_CODE res)
{
  int expr_uid = INSN_UID (EXPR_INSN_RTX (expr));

  /* Do not cache result of propagating jumps through an insn group,
     as it is always true, which is not useful outside the group.  */
  if (inside_insn_group)
    return;

  if (res == MOVEUP_EXPR_NULL)
    {
      bitmap_set_bit (INSN_ANALYZED_DEPS (insn), expr_uid);
      bitmap_set_bit (INSN_FOUND_DEPS (insn), expr_uid);
    }
  else if (res == MOVEUP_EXPR_SAME)
    {
      bitmap_set_bit (INSN_ANALYZED_DEPS (insn), expr_uid);
      bitmap_clear_bit (INSN_FOUND_DEPS (insn), expr_uid);
    }
  else if (res == MOVEUP_EXPR_AS_RHS)
    {
      bitmap_clear_bit (INSN_ANALYZED_DEPS (insn), expr_uid);
      bitmap_set_bit (INSN_FOUND_DEPS (insn), expr_uid);
    }
  else
    gcc_unreachable ();
}

/* Update hashtable on INSN with changed EXPR, old EXPR_OLD_VINSN
   and transformation type TRANS_TYPE.  */
static void
update_transformation_cache (expr_t expr, insn_t insn,
                             bool inside_insn_group,
                             enum local_trans_type trans_type,
                             vinsn_t expr_old_vinsn)
{
  struct transformed_insns *pti;

  if (inside_insn_group)
    return;

  pti = XNEW (struct transformed_insns);
  pti->vinsn_old = expr_old_vinsn;
  pti->vinsn_new = EXPR_VINSN (expr);
  pti->type = trans_type;
  pti->was_target_conflict = was_target_conflict;
  pti->ds = EXPR_SPEC_DONE_DS (expr);
  pti->needs_check = EXPR_NEEDS_SPEC_CHECK_P (expr);
  vinsn_attach (pti->vinsn_old);
  vinsn_attach (pti->vinsn_new);
  *((struct transformed_insns **)
    htab_find_slot_with_hash (INSN_TRANSFORMED_INSNS (insn),
                              pti, VINSN_HASH_RTX (expr_old_vinsn),
                              INSERT)) = pti;
}

/* Same as moveup_expr, but first looks up the result of
   transformation in caches.  */
static enum MOVEUP_EXPR_CODE
moveup_expr_cached (expr_t expr, insn_t insn, bool inside_insn_group)
{
  enum MOVEUP_EXPR_CODE res;
  bool got_answer = false;

  if (sched_verbose >= 6)
    {
      sel_print ("Moving ");
      dump_expr (expr);
      sel_print (" through %d: ", INSN_UID (insn));
    }

  if (DEBUG_INSN_P (EXPR_INSN_RTX (expr))
      && BLOCK_FOR_INSN (EXPR_INSN_RTX (expr))
      && (sel_bb_head (BLOCK_FOR_INSN (EXPR_INSN_RTX (expr)))
	  == EXPR_INSN_RTX (expr)))
    /* Don't use cached information for debug insns that are heads of
       basic blocks.  */;
  else if (try_bitmap_cache (expr, insn, inside_insn_group, &res))
    /* When inside insn group, we do not want remove stores conflicting
       with previosly issued loads.  */
    got_answer = ! inside_insn_group || res != MOVEUP_EXPR_NULL;
  else if (try_transformation_cache (expr, insn, &res))
    got_answer = true;

  if (! got_answer)
    {
      /* Invoke moveup_expr and record the results.  */
      vinsn_t expr_old_vinsn = EXPR_VINSN (expr);
      ds_t expr_old_spec_ds = EXPR_SPEC_DONE_DS (expr);
      int expr_uid = INSN_UID (VINSN_INSN_RTX (expr_old_vinsn));
      bool unique_p = VINSN_UNIQUE_P (expr_old_vinsn);
      enum local_trans_type trans_type = TRANS_SUBSTITUTION;

      /* ??? Invent something better than this.  We can't allow old_vinsn
         to go, we need it for the history vector.  */
      vinsn_attach (expr_old_vinsn);

      res = moveup_expr (expr, insn, inside_insn_group,
                         &trans_type);
      switch (res)
        {
        case MOVEUP_EXPR_NULL:
          update_bitmap_cache (expr, insn, inside_insn_group, res);
	  if (sched_verbose >= 6)
            sel_print ("removed\n");
	  break;

	case MOVEUP_EXPR_SAME:
          update_bitmap_cache (expr, insn, inside_insn_group, res);
          if (sched_verbose >= 6)
            sel_print ("unchanged\n");
	  break;

        case MOVEUP_EXPR_AS_RHS:
          gcc_assert (!unique_p || inside_insn_group);
          update_bitmap_cache (expr, insn, inside_insn_group, res);
	  if (sched_verbose >= 6)
            sel_print ("unchanged (as RHS)\n");
	  break;

	case MOVEUP_EXPR_CHANGED:
          gcc_assert (INSN_UID (EXPR_INSN_RTX (expr)) != expr_uid
                      || EXPR_SPEC_DONE_DS (expr) != expr_old_spec_ds);
          insert_in_history_vect (&EXPR_HISTORY_OF_CHANGES (expr),
                                  INSN_UID (insn), trans_type,
                                  expr_old_vinsn, EXPR_VINSN (expr),
                                  expr_old_spec_ds);
          update_transformation_cache (expr, insn, inside_insn_group,
                                       trans_type, expr_old_vinsn);
          if (sched_verbose >= 6)
            {
              sel_print ("changed: ");
              dump_expr (expr);
              sel_print ("\n");
            }
	  break;
	default:
	  gcc_unreachable ();
        }

      vinsn_detach (expr_old_vinsn);
    }

  return res;
}

/* Moves an av set AVP up through INSN, performing necessary
   transformations.  */
static void
moveup_set_expr (av_set_t *avp, insn_t insn, bool inside_insn_group)
{
  av_set_iterator i;
  expr_t expr;

  FOR_EACH_EXPR_1 (expr, i, avp)
    {

      switch (moveup_expr_cached (expr, insn, inside_insn_group))
	{
	case MOVEUP_EXPR_SAME:
        case MOVEUP_EXPR_AS_RHS:
	  break;

	case MOVEUP_EXPR_NULL:
	  av_set_iter_remove (&i);
	  break;

	case MOVEUP_EXPR_CHANGED:
          expr = merge_with_other_exprs (avp, &i, expr);
	  break;

	default:
	  gcc_unreachable ();
	}
    }
}

/* Moves AVP set along PATH.  */
static void
moveup_set_inside_insn_group (av_set_t *avp, ilist_t path)
{
  int last_cycle;

  if (sched_verbose >= 6)
    sel_print ("Moving expressions up in the insn group...\n");
  if (! path)
    return;
  last_cycle = INSN_SCHED_CYCLE (ILIST_INSN (path));
  while (path
         && INSN_SCHED_CYCLE (ILIST_INSN (path)) == last_cycle)
    {
      moveup_set_expr (avp, ILIST_INSN (path), true);
      path = ILIST_NEXT (path);
    }
}

/* Returns true if after moving EXPR along PATH it equals to EXPR_VLIW.  */
static bool
equal_after_moveup_path_p (expr_t expr, ilist_t path, expr_t expr_vliw)
{
  expr_def _tmp, *tmp = &_tmp;
  int last_cycle;
  bool res = true;

  copy_expr_onside (tmp, expr);
  last_cycle = path ? INSN_SCHED_CYCLE (ILIST_INSN (path)) : 0;
  while (path
         && res
         && INSN_SCHED_CYCLE (ILIST_INSN (path)) == last_cycle)
    {
      res = (moveup_expr_cached (tmp, ILIST_INSN (path), true)
             != MOVEUP_EXPR_NULL);
      path = ILIST_NEXT (path);
    }

  if (res)
    {
      vinsn_t tmp_vinsn = EXPR_VINSN (tmp);
      vinsn_t expr_vliw_vinsn = EXPR_VINSN (expr_vliw);

      if (tmp_vinsn != expr_vliw_vinsn)
	res = vinsn_equal_p (tmp_vinsn, expr_vliw_vinsn);
    }

  clear_expr (tmp);
  return res;
}


/* Functions that compute av and lv sets.  */

/* Returns true if INSN is not a downward continuation of the given path P in
   the current stage.  */
static bool
is_ineligible_successor (insn_t insn, ilist_t p)
{
  insn_t prev_insn;

  /* Check if insn is not deleted.  */
  if (PREV_INSN (insn) && NEXT_INSN (PREV_INSN (insn)) != insn)
    gcc_unreachable ();
  else if (NEXT_INSN (insn) && PREV_INSN (NEXT_INSN (insn)) != insn)
    gcc_unreachable ();

  /* If it's the first insn visited, then the successor is ok.  */
  if (!p)
    return false;

  prev_insn = ILIST_INSN (p);

  if (/* a backward edge.  */
      INSN_SEQNO (insn) < INSN_SEQNO (prev_insn)
      /* is already visited.  */
      || (INSN_SEQNO (insn) == INSN_SEQNO (prev_insn)
	  && (ilist_is_in_p (p, insn)
              /* We can reach another fence here and still seqno of insn
                 would be equal to seqno of prev_insn.  This is possible
                 when prev_insn is a previously created bookkeeping copy.
                 In that case it'd get a seqno of insn.  Thus, check here
                 whether insn is in current fence too.  */
              || IN_CURRENT_FENCE_P (insn)))
      /* Was already scheduled on this round.  */
      || (INSN_SEQNO (insn) > INSN_SEQNO (prev_insn)
	  && IN_CURRENT_FENCE_P (insn))
      /* An insn from another fence could also be
	 scheduled earlier even if this insn is not in
	 a fence list right now.  Check INSN_SCHED_CYCLE instead.  */
      || (!pipelining_p
          && INSN_SCHED_TIMES (insn) > 0))
    return true;
  else
    return false;
}

/* Computes the av_set below the last bb insn INSN, doing all the 'dirty work'
   of handling multiple successors and properly merging its av_sets.  P is
   the current path traversed.  WS is the size of lookahead window.
   Return the av set computed.  */
static av_set_t
compute_av_set_at_bb_end (insn_t insn, ilist_t p, int ws)
{
  struct succs_info *sinfo;
  av_set_t expr_in_all_succ_branches = NULL;
  int is;
  insn_t succ, zero_succ = NULL;
  av_set_t av1 = NULL;

  gcc_assert (sel_bb_end_p (insn));

  /* Find different kind of successors needed for correct computing of
     SPEC and TARGET_AVAILABLE attributes.  */
  sinfo = compute_succs_info (insn, SUCCS_NORMAL);

  /* Debug output.  */
  if (sched_verbose >= 6)
    {
      sel_print ("successors of bb end (%d): ", INSN_UID (insn));
      dump_insn_vector (sinfo->succs_ok);
      sel_print ("\n");
      if (sinfo->succs_ok_n != sinfo->all_succs_n)
        sel_print ("real successors num: %d\n", sinfo->all_succs_n);
    }

  /* Add insn to the tail of current path.  */
  ilist_add (&p, insn);

  FOR_EACH_VEC_ELT (sinfo->succs_ok, is, succ)
    {
      av_set_t succ_set;

      /* We will edit SUCC_SET and EXPR_SPEC field of its elements.  */
      succ_set = compute_av_set_inside_bb (succ, p, ws, true);

      av_set_split_usefulness (succ_set,
                               sinfo->probs_ok[is],
                               sinfo->all_prob);

      if (sinfo->all_succs_n > 1)
	{
          /* Find EXPR'es that came from *all* successors and save them
             into expr_in_all_succ_branches.  This set will be used later
             for calculating speculation attributes of EXPR'es.  */
          if (is == 0)
            {
              expr_in_all_succ_branches = av_set_copy (succ_set);

              /* Remember the first successor for later. */
              zero_succ = succ;
            }
          else
            {
              av_set_iterator i;
              expr_t expr;

              FOR_EACH_EXPR_1 (expr, i, &expr_in_all_succ_branches)
                if (!av_set_is_in_p (succ_set, EXPR_VINSN (expr)))
                  av_set_iter_remove (&i);
            }
	}

      /* Union the av_sets.  Check liveness restrictions on target registers
         in special case of two successors.  */
      if (sinfo->succs_ok_n == 2 && is == 1)
        {
          basic_block bb0 = BLOCK_FOR_INSN (zero_succ);
          basic_block bb1 = BLOCK_FOR_INSN (succ);

          gcc_assert (BB_LV_SET_VALID_P (bb0) && BB_LV_SET_VALID_P (bb1));
          av_set_union_and_live (&av1, &succ_set,
                                 BB_LV_SET (bb0),
                                 BB_LV_SET (bb1),
                                 insn);
        }
      else
        av_set_union_and_clear (&av1, &succ_set, insn);
    }

  /* Check liveness restrictions via hard way when there are more than
     two successors.  */
  if (sinfo->succs_ok_n > 2)
    FOR_EACH_VEC_ELT (sinfo->succs_ok, is, succ)
      {
        basic_block succ_bb = BLOCK_FOR_INSN (succ);

        gcc_assert (BB_LV_SET_VALID_P (succ_bb));
        mark_unavailable_targets (av1, BB_AV_SET (succ_bb),
                                  BB_LV_SET (succ_bb));
      }

  /* Finally, check liveness restrictions on paths leaving the region.  */
  if (sinfo->all_succs_n > sinfo->succs_ok_n)
    FOR_EACH_VEC_ELT (sinfo->succs_other, is, succ)
      mark_unavailable_targets
        (av1, NULL, BB_LV_SET (BLOCK_FOR_INSN (succ)));

  if (sinfo->all_succs_n > 1)
    {
      av_set_iterator i;
      expr_t expr;

      /* Increase the spec attribute of all EXPR'es that didn't come
	 from all successors.  */
      FOR_EACH_EXPR (expr, i, av1)
	if (!av_set_is_in_p (expr_in_all_succ_branches, EXPR_VINSN (expr)))
	  EXPR_SPEC (expr)++;

      av_set_clear (&expr_in_all_succ_branches);

      /* Do not move conditional branches through other
	 conditional branches.  So, remove all conditional
	 branches from av_set if current operator is a conditional
	 branch.  */
      av_set_substract_cond_branches (&av1);
    }

  ilist_remove (&p);
  free_succs_info (sinfo);

  if (sched_verbose >= 6)
    {
      sel_print ("av_succs (%d): ", INSN_UID (insn));
      dump_av_set (av1);
      sel_print ("\n");
    }

  return av1;
}

/* This function computes av_set for the FIRST_INSN by dragging valid
   av_set through all basic block insns either from the end of basic block
   (computed using compute_av_set_at_bb_end) or from the insn on which
   MAX_WS was exceeded.  It uses compute_av_set_at_bb_end to compute av_set
   below the basic block and handling conditional branches.
   FIRST_INSN - the basic block head, P - path consisting of the insns
   traversed on the way to the FIRST_INSN (the path is sparse, only bb heads
   and bb ends are added to the path), WS - current window size,
   NEED_COPY_P - true if we'll make a copy of av_set before returning it.  */
static av_set_t
compute_av_set_inside_bb (insn_t first_insn, ilist_t p, int ws,
			  bool need_copy_p)
{
  insn_t cur_insn;
  int end_ws = ws;
  insn_t bb_end = sel_bb_end (BLOCK_FOR_INSN (first_insn));
  insn_t after_bb_end = NEXT_INSN (bb_end);
  insn_t last_insn;
  av_set_t av = NULL;
  basic_block cur_bb = BLOCK_FOR_INSN (first_insn);

  /* Return NULL if insn is not on the legitimate downward path.  */
  if (is_ineligible_successor (first_insn, p))
    {
      if (sched_verbose >= 6)
        sel_print ("Insn %d is ineligible_successor\n", INSN_UID (first_insn));

      return NULL;
    }

  /* If insn already has valid av(insn) computed, just return it.  */
  if (AV_SET_VALID_P (first_insn))
    {
      av_set_t av_set;

      if (sel_bb_head_p (first_insn))
	av_set = BB_AV_SET (BLOCK_FOR_INSN (first_insn));
      else
	av_set = NULL;

      if (sched_verbose >= 6)
        {
          sel_print ("Insn %d has a valid av set: ", INSN_UID (first_insn));
          dump_av_set (av_set);
          sel_print ("\n");
        }

      return need_copy_p ? av_set_copy (av_set) : av_set;
    }

  ilist_add (&p, first_insn);

  /* As the result after this loop have completed, in LAST_INSN we'll
     have the insn which has valid av_set to start backward computation
     from: it either will be NULL because on it the window size was exceeded
     or other valid av_set as returned by compute_av_set for the last insn
     of the basic block.  */
  for (last_insn = first_insn; last_insn != after_bb_end;
       last_insn = NEXT_INSN (last_insn))
    {
      /* We may encounter valid av_set not only on bb_head, but also on
	 those insns on which previously MAX_WS was exceeded.  */
      if (AV_SET_VALID_P (last_insn))
	{
          if (sched_verbose >= 6)
            sel_print ("Insn %d has a valid empty av set\n", INSN_UID (last_insn));
	  break;
	}

      /* The special case: the last insn of the BB may be an
         ineligible_successor due to its SEQ_NO that was set on
	 it as a bookkeeping.  */
      if (last_insn != first_insn
          && is_ineligible_successor (last_insn, p))
	{
          if (sched_verbose >= 6)
            sel_print ("Insn %d is ineligible_successor\n", INSN_UID (last_insn));
	  break;
	}

      if (DEBUG_INSN_P (last_insn))
	continue;

      if (end_ws > max_ws)
	{
	  /* We can reach max lookahead size at bb_header, so clean av_set
	     first.  */
	  INSN_WS_LEVEL (last_insn) = global_level;

	  if (sched_verbose >= 6)
            sel_print ("Insn %d is beyond the software lookahead window size\n",
                       INSN_UID (last_insn));
	  break;
	}

      end_ws++;
    }

  /* Get the valid av_set into AV above the LAST_INSN to start backward
     computation from.  It either will be empty av_set or av_set computed from
     the successors on the last insn of the current bb.  */
  if (last_insn != after_bb_end)
    {
      av = NULL;

      /* This is needed only to obtain av_sets that are identical to
         those computed by the old compute_av_set version.  */
      if (last_insn == first_insn && !INSN_NOP_P (last_insn))
        av_set_add (&av, INSN_EXPR (last_insn));
    }
  else
    /* END_WS is always already increased by 1 if LAST_INSN == AFTER_BB_END.  */
    av = compute_av_set_at_bb_end (bb_end, p, end_ws);

  /* Compute av_set in AV starting from below the LAST_INSN up to
     location above the FIRST_INSN.  */
  for (cur_insn = PREV_INSN (last_insn); cur_insn != PREV_INSN (first_insn);
       cur_insn = PREV_INSN (cur_insn))
    if (!INSN_NOP_P (cur_insn))
      {
        expr_t expr;

        moveup_set_expr (&av, cur_insn, false);

        /* If the expression for CUR_INSN is already in the set,
           replace it by the new one.  */
        expr = av_set_lookup (av, INSN_VINSN (cur_insn));
        if (expr != NULL)
          {
            clear_expr (expr);
            copy_expr (expr, INSN_EXPR (cur_insn));
          }
        else
          av_set_add (&av, INSN_EXPR (cur_insn));
      }

  /* Clear stale bb_av_set.  */
  if (sel_bb_head_p (first_insn))
    {
      av_set_clear (&BB_AV_SET (cur_bb));
      BB_AV_SET (cur_bb) = need_copy_p ? av_set_copy (av) : av;
      BB_AV_LEVEL (cur_bb) = global_level;
    }

  if (sched_verbose >= 6)
    {
      sel_print ("Computed av set for insn %d: ", INSN_UID (first_insn));
      dump_av_set (av);
      sel_print ("\n");
    }

  ilist_remove (&p);
  return av;
}

/* Compute av set before INSN.
   INSN - the current operation (actual rtx INSN)
   P - the current path, which is list of insns visited so far
   WS - software lookahead window size.
   UNIQUE_P - TRUE, if returned av_set will be changed, hence
   if we want to save computed av_set in s_i_d, we should make a copy of it.

   In the resulting set we will have only expressions that don't have delay
   stalls and nonsubstitutable dependences.  */
static av_set_t
compute_av_set (insn_t insn, ilist_t p, int ws, bool unique_p)
{
  return compute_av_set_inside_bb (insn, p, ws, unique_p);
}

/* Propagate a liveness set LV through INSN.  */
static void
propagate_lv_set (regset lv, insn_t insn)
{
  gcc_assert (INSN_P (insn));

  if (INSN_NOP_P (insn))
    return;

  df_simulate_one_insn_backwards (BLOCK_FOR_INSN (insn), insn, lv);
}

/* Return livness set at the end of BB.  */
static regset
compute_live_after_bb (basic_block bb)
{
  edge e;
  edge_iterator ei;
  regset lv = get_clear_regset_from_pool ();

  gcc_assert (!ignore_first);

  FOR_EACH_EDGE (e, ei, bb->succs)
    if (sel_bb_empty_p (e->dest))
      {
        if (! BB_LV_SET_VALID_P (e->dest))
          {
            gcc_unreachable ();
            gcc_assert (BB_LV_SET (e->dest) == NULL);
            BB_LV_SET (e->dest) = compute_live_after_bb (e->dest);
            BB_LV_SET_VALID_P (e->dest) = true;
          }
        IOR_REG_SET (lv, BB_LV_SET (e->dest));
      }
    else
      IOR_REG_SET (lv, compute_live (sel_bb_head (e->dest)));

  return lv;
}

/* Compute the set of all live registers at the point before INSN and save
   it at INSN if INSN is bb header.  */
regset
compute_live (insn_t insn)
{
  basic_block bb = BLOCK_FOR_INSN (insn);
  insn_t final, temp;
  regset lv;

  /* Return the valid set if we're already on it.  */
  if (!ignore_first)
    {
      regset src = NULL;

      if (sel_bb_head_p (insn) && BB_LV_SET_VALID_P (bb))
        src = BB_LV_SET (bb);
      else
        {
          gcc_assert (in_current_region_p (bb));
          if (INSN_LIVE_VALID_P (insn))
            src = INSN_LIVE (insn);
        }

      if (src)
	{
	  lv = get_regset_from_pool ();
	  COPY_REG_SET (lv, src);

          if (sel_bb_head_p (insn) && ! BB_LV_SET_VALID_P (bb))
            {
              COPY_REG_SET (BB_LV_SET (bb), lv);
              BB_LV_SET_VALID_P (bb) = true;
            }

	  return_regset_to_pool (lv);
	  return lv;
	}
    }

  /* We've skipped the wrong lv_set.  Don't skip the right one.  */
  ignore_first = false;
  gcc_assert (in_current_region_p (bb));

  /* Find a valid LV set in this block or below, if needed.
     Start searching from the next insn: either ignore_first is true, or
     INSN doesn't have a correct live set.  */
  temp = NEXT_INSN (insn);
  final = NEXT_INSN (BB_END (bb));
  while (temp != final && ! INSN_LIVE_VALID_P (temp))
    temp = NEXT_INSN (temp);
  if (temp == final)
    {
      lv = compute_live_after_bb (bb);
      temp = PREV_INSN (temp);
    }
  else
    {
      lv = get_regset_from_pool ();
      COPY_REG_SET (lv, INSN_LIVE (temp));
    }

  /* Put correct lv sets on the insns which have bad sets.  */
  final = PREV_INSN (insn);
  while (temp != final)
    {
      propagate_lv_set (lv, temp);
      COPY_REG_SET (INSN_LIVE (temp), lv);
      INSN_LIVE_VALID_P (temp) = true;
      temp = PREV_INSN (temp);
    }

  /* Also put it in a BB.  */
  if (sel_bb_head_p (insn))
    {
      basic_block bb = BLOCK_FOR_INSN (insn);

      COPY_REG_SET (BB_LV_SET (bb), lv);
      BB_LV_SET_VALID_P (bb) = true;
    }

  /* We return LV to the pool, but will not clear it there.  Thus we can
     legimatelly use LV till the next use of regset_pool_get ().  */
  return_regset_to_pool (lv);
  return lv;
}

/* Update liveness sets for INSN.  */
static inline void
update_liveness_on_insn (rtx_insn *insn)
{
  ignore_first = true;
  compute_live (insn);
}

/* Compute liveness below INSN and write it into REGS.  */
static inline void
compute_live_below_insn (rtx_insn *insn, regset regs)
{
  rtx_insn *succ;
  succ_iterator si;

  FOR_EACH_SUCC_1 (succ, si, insn, SUCCS_ALL)
    IOR_REG_SET (regs, compute_live (succ));
}

/* Update the data gathered in av and lv sets starting from INSN.  */
static void
update_data_sets (rtx_insn *insn)
{
  update_liveness_on_insn (insn);
  if (sel_bb_head_p (insn))
    {
      gcc_assert (AV_LEVEL (insn) != 0);
      BB_AV_LEVEL (BLOCK_FOR_INSN (insn)) = -1;
      compute_av_set (insn, NULL, 0, 0);
    }
}


/* Helper for move_op () and find_used_regs ().
   Return speculation type for which a check should be created on the place
   of INSN.  EXPR is one of the original ops we are searching for.  */
static ds_t
get_spec_check_type_for_insn (insn_t insn, expr_t expr)
{
  ds_t to_check_ds;
  ds_t already_checked_ds = EXPR_SPEC_DONE_DS (INSN_EXPR (insn));

  to_check_ds = EXPR_SPEC_TO_CHECK_DS (expr);

  if (targetm.sched.get_insn_checked_ds)
    already_checked_ds |= targetm.sched.get_insn_checked_ds (insn);

  if (spec_info != NULL
      && (spec_info->flags & SEL_SCHED_SPEC_DONT_CHECK_CONTROL))
    already_checked_ds |= BEGIN_CONTROL;

  already_checked_ds = ds_get_speculation_types (already_checked_ds);

  to_check_ds &= ~already_checked_ds;

  return to_check_ds;
}

/* Find the set of registers that are unavailable for storing expres
   while moving ORIG_OPS up on the path starting from INSN due to
   liveness (USED_REGS) or hardware restrictions (REG_RENAME_P).

   All the original operations found during the traversal are saved in the
   ORIGINAL_INSNS list.

   REG_RENAME_P denotes the set of hardware registers that
   can not be used with renaming due to the register class restrictions,
   mode restrictions and other (the register we'll choose should be
   compatible class with the original uses, shouldn't be in call_used_regs,
   should be HARD_REGNO_RENAME_OK etc).

   Returns TRUE if we've found all original insns, FALSE otherwise.

   This function utilizes code_motion_path_driver (formerly find_used_regs_1)
   to traverse the code motion paths.  This helper function finds registers
   that are not available for storing expres while moving ORIG_OPS up on the
   path starting from INSN.  A register considered as used on the moving path,
   if one of the following conditions is not satisfied:

      (1) a register not set or read on any path from xi to an instance of
	  the original operation,
      (2) not among the live registers of the point immediately following the
          first original operation on a given downward path, except for the
	  original target register of the operation,
      (3) not live on the other path of any conditional branch that is passed
	  by the operation, in case original operations are not present on
	  both paths of the conditional branch.

   All the original operations found during the traversal are saved in the
   ORIGINAL_INSNS list.

   REG_RENAME_P->CROSSES_CALL is true, if there is a call insn on the path
   from INSN to original insn. In this case CALL_USED_REG_SET will be added
   to unavailable hard regs at the point original operation is found.  */

static bool
find_used_regs (insn_t insn, av_set_t orig_ops, regset used_regs,
		struct reg_rename  *reg_rename_p, def_list_t *original_insns)
{
  def_list_iterator i;
  def_t def;
  int res;
  bool needs_spec_check_p = false;
  expr_t expr;
  av_set_iterator expr_iter;
  struct fur_static_params sparams;
  struct cmpd_local_params lparams;

  /* We haven't visited any blocks yet.  */
  bitmap_clear (code_motion_visited_blocks);

  /* Init parameters for code_motion_path_driver.  */
  sparams.crosses_call = false;
  sparams.original_insns = original_insns;
  sparams.used_regs = used_regs;

  /* Set the appropriate hooks and data.  */
  code_motion_path_driver_info = &fur_hooks;

  res = code_motion_path_driver (insn, orig_ops, NULL, &lparams, &sparams);

  reg_rename_p->crosses_call |= sparams.crosses_call;

  gcc_assert (res == 1);
  gcc_assert (original_insns && *original_insns);

  /* ??? We calculate whether an expression needs a check when computing
     av sets.  This information is not as precise as it could be due to
     merging this bit in merge_expr.  We can do better in find_used_regs,
     but we want to avoid multiple traversals of the same code motion
     paths.  */
  FOR_EACH_EXPR (expr, expr_iter, orig_ops)
    needs_spec_check_p |= EXPR_NEEDS_SPEC_CHECK_P (expr);

  /* Mark hardware regs in REG_RENAME_P that are not suitable
     for renaming expr in INSN due to hardware restrictions (register class,
     modes compatibility etc).  */
  FOR_EACH_DEF (def, i, *original_insns)
    {
      vinsn_t vinsn = INSN_VINSN (def->orig_insn);

      if (VINSN_SEPARABLE_P (vinsn))
	mark_unavailable_hard_regs (def, reg_rename_p, used_regs);

      /* Do not allow clobbering of ld.[sa] address in case some of the
         original operations need a check.  */
      if (needs_spec_check_p)
	IOR_REG_SET (used_regs, VINSN_REG_USES (vinsn));
    }

  return true;
}


/* Functions to choose the best insn from available ones.  */

/* Adjusts the priority for EXPR using the backend *_adjust_priority hook.  */
static int
sel_target_adjust_priority (expr_t expr)
{
  int priority = EXPR_PRIORITY (expr);
  int new_priority;

  if (targetm.sched.adjust_priority)
    new_priority = targetm.sched.adjust_priority (EXPR_INSN_RTX (expr), priority);
  else
    new_priority = priority;

  /* If the priority has changed, adjust EXPR_PRIORITY_ADJ accordingly.  */
  EXPR_PRIORITY_ADJ (expr) = new_priority - EXPR_PRIORITY (expr);

  gcc_assert (EXPR_PRIORITY_ADJ (expr) >= 0);

  if (sched_verbose >= 4)
    sel_print ("sel_target_adjust_priority: insn %d,  %d+%d = %d.\n",
	       INSN_UID (EXPR_INSN_RTX (expr)), EXPR_PRIORITY (expr),
	       EXPR_PRIORITY_ADJ (expr), new_priority);

  return new_priority;
}

/* Rank two available exprs for schedule.  Never return 0 here.  */
static int
sel_rank_for_schedule (const void *x, const void *y)
{
  expr_t tmp = *(const expr_t *) y;
  expr_t tmp2 = *(const expr_t *) x;
  insn_t tmp_insn, tmp2_insn;
  vinsn_t tmp_vinsn, tmp2_vinsn;
  int val;

  tmp_vinsn = EXPR_VINSN (tmp);
  tmp2_vinsn = EXPR_VINSN (tmp2);
  tmp_insn = EXPR_INSN_RTX (tmp);
  tmp2_insn = EXPR_INSN_RTX (tmp2);

  /* Schedule debug insns as early as possible.  */
  if (DEBUG_INSN_P (tmp_insn) && !DEBUG_INSN_P (tmp2_insn))
    return -1;
  else if (DEBUG_INSN_P (tmp2_insn))
    return 1;

  /* Prefer SCHED_GROUP_P insns to any others.  */
  if (SCHED_GROUP_P (tmp_insn) != SCHED_GROUP_P (tmp2_insn))
    {
      if (VINSN_UNIQUE_P (tmp_vinsn) && VINSN_UNIQUE_P (tmp2_vinsn))
        return SCHED_GROUP_P (tmp2_insn) ? 1 : -1;

      /* Now uniqueness means SCHED_GROUP_P is set, because schedule groups
         cannot be cloned.  */
      if (VINSN_UNIQUE_P (tmp2_vinsn))
        return 1;
      return -1;
    }

  /* Discourage scheduling of speculative checks.  */
  val = (sel_insn_is_speculation_check (tmp_insn)
	 - sel_insn_is_speculation_check (tmp2_insn));
  if (val)
    return val;

  /* Prefer not scheduled insn over scheduled one.  */
  if (EXPR_SCHED_TIMES (tmp) > 0 || EXPR_SCHED_TIMES (tmp2) > 0)
    {
      val = EXPR_SCHED_TIMES (tmp) - EXPR_SCHED_TIMES (tmp2);
      if (val)
	return val;
    }

  /* Prefer jump over non-jump instruction.  */
  if (control_flow_insn_p (tmp_insn) && !control_flow_insn_p (tmp2_insn))
    return -1;
  else if (control_flow_insn_p (tmp2_insn) && !control_flow_insn_p (tmp_insn))
    return 1;

  /* Prefer an expr with non-zero usefulness.  */
  int u1 = EXPR_USEFULNESS (tmp), u2 = EXPR_USEFULNESS (tmp2);

  if (u1 == 0)
    {
      if (u2 == 0)
        u1 = u2 = 1;
      else
        return 1;
    }
  else if (u2 == 0)
    return -1;

  /* Prefer an expr with greater priority.  */
  val = (u2 * (EXPR_PRIORITY (tmp2) + EXPR_PRIORITY_ADJ (tmp2))
         - u1 * (EXPR_PRIORITY (tmp) + EXPR_PRIORITY_ADJ (tmp)));
  if (val)
    return val;

  if (spec_info != NULL && spec_info->mask != 0)
    /* This code was taken from haifa-sched.c: rank_for_schedule ().  */
    {
      ds_t ds1, ds2;
      dw_t dw1, dw2;
      int dw;

      ds1 = EXPR_SPEC_DONE_DS (tmp);
      if (ds1)
	dw1 = ds_weak (ds1);
      else
	dw1 = NO_DEP_WEAK;

      ds2 = EXPR_SPEC_DONE_DS (tmp2);
      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 dw;
    }

  /* Prefer an old insn to a bookkeeping insn.  */
  if (INSN_UID (tmp_insn) < first_emitted_uid
      && INSN_UID (tmp2_insn) >= first_emitted_uid)
    return -1;
  if (INSN_UID (tmp_insn) >= first_emitted_uid
      && INSN_UID (tmp2_insn) < first_emitted_uid)
    return 1;

  /* Prefer an insn with smaller UID, as a last resort.
     We can't safely use INSN_LUID as it is defined only for those insns
     that are in the stream.  */
  return INSN_UID (tmp_insn) - INSN_UID (tmp2_insn);
}

/* Filter out expressions from av set pointed to by AV_PTR
   that are pipelined too many times.  */
static void
process_pipelined_exprs (av_set_t *av_ptr)
{
  expr_t expr;
  av_set_iterator si;

  /* Don't pipeline already pipelined code as that would increase
     number of unnecessary register moves.  */
  FOR_EACH_EXPR_1 (expr, si, av_ptr)
    {
      if (EXPR_SCHED_TIMES (expr)
	  >= PARAM_VALUE (PARAM_SELSCHED_MAX_SCHED_TIMES))
	av_set_iter_remove (&si);
    }
}

/* Filter speculative insns from AV_PTR if we don't want them.  */
static void
process_spec_exprs (av_set_t *av_ptr)
{
  expr_t expr;
  av_set_iterator si;

  if (spec_info == NULL)
    return;

  /* Scan *AV_PTR to find out if we want to consider speculative
     instructions for scheduling.  */
  FOR_EACH_EXPR_1 (expr, si, av_ptr)
    {
      ds_t ds;

      ds = EXPR_SPEC_DONE_DS (expr);

      /* The probability of a success is too low - don't speculate.  */
      if ((ds & SPECULATIVE)
          && (ds_weak (ds) < spec_info->data_weakness_cutoff
              || EXPR_USEFULNESS (expr) < spec_info->control_weakness_cutoff
	      || (pipelining_p && false
		  && (ds & DATA_SPEC)
		  && (ds & CONTROL_SPEC))))
        {
          av_set_iter_remove (&si);
          continue;
        }
    }
}

/* Search for any use-like insns in AV_PTR and decide on scheduling
   them.  Return one when found, and NULL otherwise.
   Note that we check here whether a USE could be scheduled to avoid
   an infinite loop later.  */
static expr_t
process_use_exprs (av_set_t *av_ptr)
{
  expr_t expr;
  av_set_iterator si;
  bool uses_present_p = false;
  bool try_uses_p = true;

  FOR_EACH_EXPR_1 (expr, si, av_ptr)
    {
      /* This will also initialize INSN_CODE for later use.  */
      if (recog_memoized (EXPR_INSN_RTX (expr)) < 0)
        {
          /* If we have a USE in *AV_PTR that was not scheduled yet,
             do so because it will do good only.  */
          if (EXPR_SCHED_TIMES (expr) <= 0)
            {
              if (EXPR_TARGET_AVAILABLE (expr) == 1)
                return expr;

              av_set_iter_remove (&si);
            }
          else
            {
              gcc_assert (pipelining_p);

              uses_present_p = true;
            }
        }
      else
        try_uses_p = false;
    }

  if (uses_present_p)
    {
      /* If we don't want to schedule any USEs right now and we have some
           in *AV_PTR, remove them, else just return the first one found.  */
      if (!try_uses_p)
        {
          FOR_EACH_EXPR_1 (expr, si, av_ptr)
            if (INSN_CODE (EXPR_INSN_RTX (expr)) < 0)
              av_set_iter_remove (&si);
        }
      else
        {
          FOR_EACH_EXPR_1 (expr, si, av_ptr)
            {
              gcc_assert (INSN_CODE (EXPR_INSN_RTX (expr)) < 0);

              if (EXPR_TARGET_AVAILABLE (expr) == 1)
                return expr;

              av_set_iter_remove (&si);
            }
        }
    }

  return NULL;
}

/* Lookup EXPR in VINSN_VEC and return TRUE if found.  Also check patterns from
   EXPR's history of changes.  */
static bool
vinsn_vec_has_expr_p (vinsn_vec_t vinsn_vec, expr_t expr)
{
  vinsn_t vinsn, expr_vinsn;
  int n;
  unsigned i;

  /* Start with checking expr itself and then proceed with all the old forms
     of expr taken from its history vector.  */
  for (i = 0, expr_vinsn = EXPR_VINSN (expr);
       expr_vinsn;
       expr_vinsn = (i < EXPR_HISTORY_OF_CHANGES (expr).length ()
		     ? EXPR_HISTORY_OF_CHANGES (expr)[i++].old_expr_vinsn
		     : NULL))
    FOR_EACH_VEC_ELT (vinsn_vec, n, vinsn)
      if (VINSN_SEPARABLE_P (vinsn))
	{
	  if (vinsn_equal_p (vinsn, expr_vinsn))
	    return true;
	}
      else
	{
	  /* For non-separable instructions, the blocking insn can have
	     another pattern due to substitution, and we can't choose
	     different register as in the above case.  Check all registers
	     being written instead.  */
	  if (bitmap_intersect_p (VINSN_REG_SETS (vinsn),
				  VINSN_REG_SETS (expr_vinsn)))
	    return true;
	}

  return false;
}

/* Return true if either of expressions from ORIG_OPS can be blocked
   by previously created bookkeeping code.  STATIC_PARAMS points to static
   parameters of move_op.  */
static bool
av_set_could_be_blocked_by_bookkeeping_p (av_set_t orig_ops, void *static_params)
{
  expr_t expr;
  av_set_iterator iter;
  moveop_static_params_p sparams;

  /* This checks that expressions in ORIG_OPS are not blocked by bookkeeping
     created while scheduling on another fence.  */
  FOR_EACH_EXPR (expr, iter, orig_ops)
    if (vinsn_vec_has_expr_p (vec_bookkeeping_blocked_vinsns, expr))
      return true;

  gcc_assert (code_motion_path_driver_info == &move_op_hooks);
  sparams = (moveop_static_params_p) static_params;

  /* Expressions can be also blocked by bookkeeping created during current
     move_op.  */
  if (bitmap_bit_p (current_copies, INSN_UID (sparams->failed_insn)))
    FOR_EACH_EXPR (expr, iter, orig_ops)
      if (moveup_expr_cached (expr, sparams->failed_insn, false) != MOVEUP_EXPR_NULL)
        return true;

  /* Expressions in ORIG_OPS may have wrong destination register due to
     renaming.  Check with the right register instead.  */
  if (sparams->dest && REG_P (sparams->dest))
    {
      rtx reg = sparams->dest;
      vinsn_t failed_vinsn = INSN_VINSN (sparams->failed_insn);

      if (register_unavailable_p (VINSN_REG_SETS (failed_vinsn), reg)
	  || register_unavailable_p (VINSN_REG_USES (failed_vinsn), reg)
	  || register_unavailable_p (VINSN_REG_CLOBBERS (failed_vinsn), reg))
	return true;
    }

  return false;
}

/* Clear VINSN_VEC and detach vinsns.  */
static void
vinsn_vec_clear (vinsn_vec_t *vinsn_vec)
{
  unsigned len = vinsn_vec->length ();
  if (len > 0)
    {
      vinsn_t vinsn;
      int n;

      FOR_EACH_VEC_ELT (*vinsn_vec, n, vinsn)
        vinsn_detach (vinsn);
      vinsn_vec->block_remove (0, len);
    }
}

/* Add the vinsn of EXPR to the VINSN_VEC.  */
static void
vinsn_vec_add (vinsn_vec_t *vinsn_vec, expr_t expr)
{
  vinsn_attach (EXPR_VINSN (expr));
  vinsn_vec->safe_push (EXPR_VINSN (expr));
}

/* Free the vector representing blocked expressions.  */
static void
vinsn_vec_free (vinsn_vec_t &vinsn_vec)
{
  vinsn_vec.release ();
}

/* Increase EXPR_PRIORITY_ADJ for INSN by AMOUNT.  */

void sel_add_to_insn_priority (rtx insn, int amount)
{
  EXPR_PRIORITY_ADJ (INSN_EXPR (insn)) += amount;

  if (sched_verbose >= 2)
    sel_print ("sel_add_to_insn_priority: insn %d, by %d (now %d+%d).\n",
	       INSN_UID (insn), amount, EXPR_PRIORITY (INSN_EXPR (insn)),
	       EXPR_PRIORITY_ADJ (INSN_EXPR (insn)));
}

/* Turn AV into a vector, filter inappropriate insns and sort it.  Return
   true if there is something to schedule.  BNDS and FENCE are current
   boundaries and fence, respectively.  If we need to stall for some cycles
   before an expr from AV would become available, write this number to
   *PNEED_STALL.  */
static bool
fill_vec_av_set (av_set_t av, blist_t bnds, fence_t fence,
                 int *pneed_stall)
{
  av_set_iterator si;
  expr_t expr;
  int sched_next_worked = 0, stalled, n;
  static int av_max_prio, est_ticks_till_branch;
  int min_need_stall = -1;
  deps_t dc = BND_DC (BLIST_BND (bnds));

  /* Bail out early when the ready list contained only USEs/CLOBBERs that are
     already scheduled.  */
  if (av == NULL)
    return false;

  /* Empty vector from the previous stuff.  */
  if (vec_av_set.length () > 0)
    vec_av_set.block_remove (0, vec_av_set.length ());

  /* Turn the set into a vector for sorting and call sel_target_adjust_priority
     for each insn.  */
  gcc_assert (vec_av_set.is_empty ());
  FOR_EACH_EXPR (expr, si, av)
    {
      vec_av_set.safe_push (expr);

      gcc_assert (EXPR_PRIORITY_ADJ (expr) == 0 || *pneed_stall);

      /* Adjust priority using target backend hook.  */
      sel_target_adjust_priority (expr);
    }

  /* Sort the vector.  */
  vec_av_set.qsort (sel_rank_for_schedule);

  /* We record maximal priority of insns in av set for current instruction
     group.  */
  if (FENCE_STARTS_CYCLE_P (fence))
    av_max_prio = est_ticks_till_branch = INT_MIN;

  /* Filter out inappropriate expressions.  Loop's direction is reversed to
     visit "best" instructions first.  We assume that vec::unordered_remove
     moves last element in place of one being deleted.  */
  for (n = vec_av_set.length () - 1, stalled = 0; n >= 0; n--)
    {
      expr_t expr = vec_av_set[n];
      insn_t insn = EXPR_INSN_RTX (expr);
      signed char target_available;
      bool is_orig_reg_p = true;
      int need_cycles, new_prio;
      bool fence_insn_p = INSN_UID (insn) == INSN_UID (FENCE_INSN (fence));

      /* Don't allow any insns other than from SCHED_GROUP if we have one.  */
      if (FENCE_SCHED_NEXT (fence) && insn != FENCE_SCHED_NEXT (fence))
        {
          vec_av_set.unordered_remove (n);
          continue;
        }

      /* Set number of sched_next insns (just in case there
         could be several).  */
      if (FENCE_SCHED_NEXT (fence))
        sched_next_worked++;

      /* Check all liveness requirements and try renaming.
         FIXME: try to minimize calls to this.  */
      target_available = EXPR_TARGET_AVAILABLE (expr);

      /* If insn was already scheduled on the current fence,
	 set TARGET_AVAILABLE to -1 no matter what expr's attribute says.  */
      if (vinsn_vec_has_expr_p (vec_target_unavailable_vinsns, expr)
	  && !fence_insn_p)
	target_available = -1;

      /* If the availability of the EXPR is invalidated by the insertion of
	 bookkeeping earlier, make sure that we won't choose this expr for
	 scheduling if it's not separable, and if it is separable, then
	 we have to recompute the set of available registers for it.  */
      if (vinsn_vec_has_expr_p (vec_bookkeeping_blocked_vinsns, expr))
	{
          vec_av_set.unordered_remove (n);
          if (sched_verbose >= 4)
            sel_print ("Expr %d is blocked by bookkeeping inserted earlier\n",
                       INSN_UID (insn));
          continue;
        }

      if (target_available == true)
	{
          /* Do nothing -- we can use an existing register.  */
	  is_orig_reg_p = EXPR_SEPARABLE_P (expr);
        }
      else if (/* Non-separable instruction will never
                  get another register. */
               (target_available == false
                && !EXPR_SEPARABLE_P (expr))
               /* Don't try to find a register for low-priority expression.  */
               || (int) vec_av_set.length () - 1 - n >= max_insns_to_rename
               /* ??? FIXME: Don't try to rename data speculation.  */
               || (EXPR_SPEC_DONE_DS (expr) & BEGIN_DATA)
               || ! find_best_reg_for_expr (expr, bnds, &is_orig_reg_p))
        {
          vec_av_set.unordered_remove (n);
          if (sched_verbose >= 4)
            sel_print ("Expr %d has no suitable target register\n",
                       INSN_UID (insn));

	  /* A fence insn should not get here.  */
	  gcc_assert (!fence_insn_p);
	  continue;
        }

      /* At this point a fence insn should always be available.  */
      gcc_assert (!fence_insn_p
		  || INSN_UID (FENCE_INSN (fence)) == INSN_UID (EXPR_INSN_RTX (expr)));

      /* Filter expressions that need to be renamed or speculated when
	 pipelining, because compensating register copies or speculation
	 checks are likely to be placed near the beginning of the loop,
	 causing a stall.  */
      if (pipelining_p && EXPR_ORIG_SCHED_CYCLE (expr) > 0
	  && (!is_orig_reg_p || EXPR_SPEC_DONE_DS (expr) != 0))
	{
	  /* Estimation of number of cycles until loop branch for
	     renaming/speculation to be successful.  */
	  int need_n_ticks_till_branch = sel_vinsn_cost (EXPR_VINSN (expr));

	  if ((int) current_loop_nest->ninsns < 9)
	    {
	      vec_av_set.unordered_remove (n);
	      if (sched_verbose >= 4)
		sel_print ("Pipelining expr %d will likely cause stall\n",
			   INSN_UID (insn));
	      continue;
	    }

	  if ((int) current_loop_nest->ninsns - num_insns_scheduled
	      < need_n_ticks_till_branch * issue_rate / 2
	      && est_ticks_till_branch < need_n_ticks_till_branch)
	     {
	       vec_av_set.unordered_remove (n);
	       if (sched_verbose >= 4)
		 sel_print ("Pipelining expr %d will likely cause stall\n",
			    INSN_UID (insn));
	       continue;
	     }
	}

      /* We want to schedule speculation checks as late as possible.  Discard
	 them from av set if there are instructions with higher priority.  */
      if (sel_insn_is_speculation_check (insn)
	  && EXPR_PRIORITY (expr) < av_max_prio)
	{
          stalled++;
          min_need_stall = min_need_stall < 0 ? 1 : MIN (min_need_stall, 1);
          vec_av_set.unordered_remove (n);
	  if (sched_verbose >= 4)
	    sel_print ("Delaying speculation check %d until its first use\n",
		       INSN_UID (insn));
	  continue;
	}

      /* Ignore EXPRs available from pipelining to update AV_MAX_PRIO.  */
      if (EXPR_ORIG_SCHED_CYCLE (expr) <= 0)
	av_max_prio = MAX (av_max_prio, EXPR_PRIORITY (expr));

      /* Don't allow any insns whose data is not yet ready.
         Check first whether we've already tried them and failed.  */
      if (INSN_UID (insn) < FENCE_READY_TICKS_SIZE (fence))
	{
          need_cycles = (FENCE_READY_TICKS (fence)[INSN_UID (insn)]
			 - FENCE_CYCLE (fence));
	  if (EXPR_ORIG_SCHED_CYCLE (expr) <= 0)
	    est_ticks_till_branch = MAX (est_ticks_till_branch,
					 EXPR_PRIORITY (expr) + need_cycles);

	  if (need_cycles > 0)
	    {
	      stalled++;
	      min_need_stall = (min_need_stall < 0
				? need_cycles
				: MIN (min_need_stall, need_cycles));
	      vec_av_set.unordered_remove (n);

	      if (sched_verbose >= 4)
		sel_print ("Expr %d is not ready until cycle %d (cached)\n",
			   INSN_UID (insn),
			   FENCE_READY_TICKS (fence)[INSN_UID (insn)]);
	      continue;
	    }
	}

      /* Now resort to dependence analysis to find whether EXPR might be
         stalled due to dependencies from FENCE's context.  */
      need_cycles = tick_check_p (expr, dc, fence);
      new_prio = EXPR_PRIORITY (expr) + EXPR_PRIORITY_ADJ (expr) + need_cycles;

      if (EXPR_ORIG_SCHED_CYCLE (expr) <= 0)
	est_ticks_till_branch = MAX (est_ticks_till_branch,
				     new_prio);

      if (need_cycles > 0)
        {
          if (INSN_UID (insn) >= FENCE_READY_TICKS_SIZE (fence))
            {
              int new_size = INSN_UID (insn) * 3 / 2;

              FENCE_READY_TICKS (fence)
                = (int *) xrecalloc (FENCE_READY_TICKS (fence),
                                     new_size, FENCE_READY_TICKS_SIZE (fence),
                                     sizeof (int));
            }
          FENCE_READY_TICKS (fence)[INSN_UID (insn)]
            = FENCE_CYCLE (fence) + need_cycles;

          stalled++;
          min_need_stall = (min_need_stall < 0
                            ? need_cycles
                            : MIN (min_need_stall, need_cycles));

          vec_av_set.unordered_remove (n);

          if (sched_verbose >= 4)
            sel_print ("Expr %d is not ready yet until cycle %d\n",
                       INSN_UID (insn),
                       FENCE_READY_TICKS (fence)[INSN_UID (insn)]);
          continue;
        }

      if (sched_verbose >= 4)
        sel_print ("Expr %d is ok\n", INSN_UID (insn));
      min_need_stall = 0;
    }

  /* Clear SCHED_NEXT.  */
  if (FENCE_SCHED_NEXT (fence))
    {
      gcc_assert (sched_next_worked == 1);
      FENCE_SCHED_NEXT (fence) = NULL;
    }

  /* No need to stall if this variable was not initialized.  */
  if (min_need_stall < 0)
    min_need_stall = 0;

  if (vec_av_set.is_empty ())
    {
      /* We need to set *pneed_stall here, because later we skip this code
         when ready list is empty.  */
      *pneed_stall = min_need_stall;
      return false;
    }
  else
    gcc_assert (min_need_stall == 0);

  /* Sort the vector.  */
  vec_av_set.qsort (sel_rank_for_schedule);

  if (sched_verbose >= 4)
    {
      sel_print ("Total ready exprs: %d, stalled: %d\n",
                 vec_av_set.length (), stalled);
      sel_print ("Sorted av set (%d): ", vec_av_set.length ());
      FOR_EACH_VEC_ELT (vec_av_set, n, expr)
        dump_expr (expr);
      sel_print ("\n");
    }

  *pneed_stall = 0;
  return true;
}

/* Convert a vectored and sorted av set to the ready list that
   the rest of the backend wants to see.  */
static void
convert_vec_av_set_to_ready (void)
{
  int n;
  expr_t expr;

  /* Allocate and fill the ready list from the sorted vector.  */
  ready.n_ready = vec_av_set.length ();
  ready.first = ready.n_ready - 1;

  gcc_assert (ready.n_ready > 0);

  if (ready.n_ready > max_issue_size)
    {
      max_issue_size = ready.n_ready;
      sched_extend_ready_list (ready.n_ready);
    }

  FOR_EACH_VEC_ELT (vec_av_set, n, expr)
    {
      vinsn_t vi = EXPR_VINSN (expr);
      insn_t insn = VINSN_INSN_RTX (vi);

      ready_try[n] = 0;
      ready.vec[n] = insn;
    }
}

/* Initialize ready list from *AV_PTR for the max_issue () call.
   If any unrecognizable insn found in *AV_PTR, return it (and skip
   max_issue).  BND and FENCE are current boundary and fence,
   respectively.  If we need to stall for some cycles before an expr
   from *AV_PTR would become available, write this number to *PNEED_STALL.  */
static expr_t
fill_ready_list (av_set_t *av_ptr, blist_t bnds, fence_t fence,
                 int *pneed_stall)
{
  expr_t expr;

  /* We do not support multiple boundaries per fence.  */
  gcc_assert (BLIST_NEXT (bnds) == NULL);

  /* Process expressions required special handling, i.e.  pipelined,
     speculative and recog() < 0 expressions first.  */
  process_pipelined_exprs (av_ptr);
  process_spec_exprs (av_ptr);

  /* A USE could be scheduled immediately.  */
  expr = process_use_exprs (av_ptr);
  if (expr)
    {
      *pneed_stall = 0;
      return expr;
    }

  /* Turn the av set to a vector for sorting.  */
  if (! fill_vec_av_set (*av_ptr, bnds, fence, pneed_stall))
    {
      ready.n_ready = 0;
      return NULL;
    }

  /* Build the final ready list.  */
  convert_vec_av_set_to_ready ();
  return NULL;
}

/* Wrapper for dfa_new_cycle ().  Returns TRUE if cycle was advanced.  */
static bool
sel_dfa_new_cycle (insn_t insn, fence_t fence)
{
  int last_scheduled_cycle = FENCE_LAST_SCHEDULED_INSN (fence)
                             ? INSN_SCHED_CYCLE (FENCE_LAST_SCHEDULED_INSN (fence))
                             : FENCE_CYCLE (fence) - 1;
  bool res = false;
  int sort_p = 0;

  if (!targetm.sched.dfa_new_cycle)
    return false;

  memcpy (curr_state, FENCE_STATE (fence), dfa_state_size);

  while (!sort_p && targetm.sched.dfa_new_cycle (sched_dump, sched_verbose,
                                                 insn, last_scheduled_cycle,
                                                 FENCE_CYCLE (fence), &sort_p))
    {
      memcpy (FENCE_STATE (fence), curr_state, dfa_state_size);
      advance_one_cycle (fence);
      memcpy (curr_state, FENCE_STATE (fence), dfa_state_size);
      res = true;
    }

  return res;
}

/* Invoke reorder* target hooks on the ready list.  Return the number of insns
   we can issue.  FENCE is the current fence.  */
static int
invoke_reorder_hooks (fence_t fence)
{
  int issue_more;
  bool ran_hook = false;

  /* Call the reorder hook at the beginning of the cycle, and call
     the reorder2 hook in the middle of the cycle.  */
  if (FENCE_ISSUED_INSNS (fence) == 0)
    {
      if (targetm.sched.reorder
          && !SCHED_GROUP_P (ready_element (&ready, 0))
          && ready.n_ready > 1)
        {
          /* Don't give reorder the most prioritized insn as it can break
             pipelining.  */
          if (pipelining_p)
            --ready.n_ready;

          issue_more
            = targetm.sched.reorder (sched_dump, sched_verbose,
                                     ready_lastpos (&ready),
                                     &ready.n_ready, FENCE_CYCLE (fence));

          if (pipelining_p)
            ++ready.n_ready;

          ran_hook = true;
        }
      else
        /* Initialize can_issue_more for variable_issue.  */
        issue_more = issue_rate;
    }
  else if (targetm.sched.reorder2
           && !SCHED_GROUP_P (ready_element (&ready, 0)))
    {
      if (ready.n_ready == 1)
        issue_more =
          targetm.sched.reorder2 (sched_dump, sched_verbose,
                                  ready_lastpos (&ready),
                                  &ready.n_ready, FENCE_CYCLE (fence));
      else
        {
          if (pipelining_p)
            --ready.n_ready;

          issue_more =
            targetm.sched.reorder2 (sched_dump, sched_verbose,
                                    ready.n_ready
                                    ? ready_lastpos (&ready) : NULL,
                                    &ready.n_ready, FENCE_CYCLE (fence));

          if (pipelining_p)
            ++ready.n_ready;
        }

      ran_hook = true;
    }
  else
    issue_more = FENCE_ISSUE_MORE (fence);

  /* Ensure that ready list and vec_av_set are in line with each other,
     i.e. vec_av_set[i] == ready_element (&ready, i).  */
  if (issue_more && ran_hook)
    {
      int i, j, n;
      rtx_insn **arr = ready.vec;
      expr_t *vec = vec_av_set.address ();

      for (i = 0, n = ready.n_ready; i < n; i++)
        if (EXPR_INSN_RTX (vec[i]) != arr[i])
          {
            for (j = i; j < n; j++)
              if (EXPR_INSN_RTX (vec[j]) == arr[i])
                break;
            gcc_assert (j < n);

	    std::swap (vec[i], vec[j]);
          }
    }

  return issue_more;
}

/* Return an EXPR corresponding to INDEX element of ready list, if
   FOLLOW_READY_ELEMENT is true (i.e., an expr of
   ready_element (&ready, INDEX) will be returned), and to INDEX element of
   ready.vec otherwise.  */
static inline expr_t
find_expr_for_ready (int index, bool follow_ready_element)
{
  expr_t expr;
  int real_index;

  real_index = follow_ready_element ? ready.first - index : index;

  expr = vec_av_set[real_index];
  gcc_assert (ready.vec[real_index] == EXPR_INSN_RTX (expr));

  return expr;
}

/* Calculate insns worth trying via lookahead_guard hook.  Return a number
   of such insns found.  */
static int
invoke_dfa_lookahead_guard (void)
{
  int i, n;
  bool have_hook
    = targetm.sched.first_cycle_multipass_dfa_lookahead_guard != NULL;

  if (sched_verbose >= 2)
    sel_print ("ready after reorder: ");

  for (i = 0, n = 0; i < ready.n_ready; i++)
    {
      expr_t expr;
      insn_t insn;
      int r;

      /* In this loop insn is Ith element of the ready list given by
         ready_element, not Ith element of ready.vec.  */
      insn = ready_element (&ready, i);

      if (! have_hook || i == 0)
        r = 0;
      else
        r = targetm.sched.first_cycle_multipass_dfa_lookahead_guard (insn, i);

      gcc_assert (INSN_CODE (insn) >= 0);

      /* Only insns with ready_try = 0 can get here
         from fill_ready_list.  */
      gcc_assert (ready_try [i] == 0);
      ready_try[i] = r;
      if (!r)
        n++;

      expr = find_expr_for_ready (i, true);

      if (sched_verbose >= 2)
        {
          dump_vinsn (EXPR_VINSN (expr));
          sel_print (":%d; ", ready_try[i]);
        }
    }

  if (sched_verbose >= 2)
    sel_print ("\n");
  return n;
}

/* Calculate the number of privileged insns and return it.  */
static int
calculate_privileged_insns (void)
{
  expr_t cur_expr, min_spec_expr = NULL;
  int privileged_n = 0, i;

  for (i = 0; i < ready.n_ready; i++)
    {
      if (ready_try[i])
        continue;

      if (! min_spec_expr)
	min_spec_expr = find_expr_for_ready (i, true);

      cur_expr = find_expr_for_ready (i, true);

      if (EXPR_SPEC (cur_expr) > EXPR_SPEC (min_spec_expr))
        break;

      ++privileged_n;
    }

  if (i == ready.n_ready)
    privileged_n = 0;

  if (sched_verbose >= 2)
    sel_print ("privileged_n: %d insns with SPEC %d\n",
               privileged_n, privileged_n ? EXPR_SPEC (min_spec_expr) : -1);
  return privileged_n;
}

/* Call the rest of the hooks after the choice was made.  Return
   the number of insns that still can be issued given that the current
   number is ISSUE_MORE.  FENCE and BEST_INSN are the current fence
   and the insn chosen for scheduling, respectively.  */
static int
invoke_aftermath_hooks (fence_t fence, rtx_insn *best_insn, int issue_more)
{
  gcc_assert (INSN_P (best_insn));

  /* First, call dfa_new_cycle, and then variable_issue, if available.  */
  sel_dfa_new_cycle (best_insn, fence);

  if (targetm.sched.variable_issue)
    {
      memcpy (curr_state, FENCE_STATE (fence), dfa_state_size);
      issue_more =
        targetm.sched.variable_issue (sched_dump, sched_verbose, best_insn,
                                      issue_more);
      memcpy (FENCE_STATE (fence), curr_state, dfa_state_size);
    }
  else if (!DEBUG_INSN_P (best_insn)
	   && GET_CODE (PATTERN (best_insn)) != USE
	   && GET_CODE (PATTERN (best_insn)) != CLOBBER)
    issue_more--;

  return issue_more;
}

/* Estimate the cost of issuing INSN on DFA state STATE.  */
static int
estimate_insn_cost (rtx_insn *insn, state_t state)
{
  static state_t temp = NULL;
  int cost;

  if (!temp)
    temp = xmalloc (dfa_state_size);

  memcpy (temp, state, dfa_state_size);
  cost = state_transition (temp, insn);

  if (cost < 0)
    return 0;
  else if (cost == 0)
    return 1;
  return cost;
}

/* Return the cost of issuing EXPR on the FENCE as estimated by DFA.
   This function properly handles ASMs, USEs etc.  */
static int
get_expr_cost (expr_t expr, fence_t fence)
{
  rtx_insn *insn = EXPR_INSN_RTX (expr);

  if (recog_memoized (insn) < 0)
    {
      if (!FENCE_STARTS_CYCLE_P (fence)
	  && INSN_ASM_P (insn))
	/* This is asm insn which is tryed to be issued on the
	   cycle not first.  Issue it on the next cycle.  */
	return 1;
      else
	/* A USE insn, or something else we don't need to
	   understand.  We can't pass these directly to
	   state_transition because it will trigger a
	   fatal error for unrecognizable insns.  */
	return 0;
    }
  else
    return estimate_insn_cost (insn, FENCE_STATE (fence));
}

/* Find the best insn for scheduling, either via max_issue or just take
   the most prioritized available.  */
static int
choose_best_insn (fence_t fence, int privileged_n, int *index)
{
  int can_issue = 0;

  if (dfa_lookahead > 0)
    {
      cycle_issued_insns = FENCE_ISSUED_INSNS (fence);
      /* TODO: pass equivalent of first_cycle_insn_p to max_issue ().  */
      can_issue = max_issue (&ready, privileged_n,
                             FENCE_STATE (fence), true, index);
      if (sched_verbose >= 2)
        sel_print ("max_issue: we can issue %d insns, already did %d insns\n",
                   can_issue, FENCE_ISSUED_INSNS (fence));
    }
  else
    {
      /* We can't use max_issue; just return the first available element.  */
      int i;

      for (i = 0; i < ready.n_ready; i++)
	{
	  expr_t expr = find_expr_for_ready (i, true);

	  if (get_expr_cost (expr, fence) < 1)
	    {
	      can_issue = can_issue_more;
	      *index = i;

	      if (sched_verbose >= 2)
		sel_print ("using %dth insn from the ready list\n", i + 1);

	      break;
	    }
	}

      if (i == ready.n_ready)
	{
	  can_issue = 0;
	  *index = -1;
	}
    }

  return can_issue;
}

/* Choose the best expr from *AV_VLIW_PTR and a suitable register for it.
   BNDS and FENCE are current boundaries and scheduling fence respectively.
   Return the expr found and NULL if nothing can be issued atm.
   Write to PNEED_STALL the number of cycles to stall if no expr was found.  */
static expr_t
find_best_expr (av_set_t *av_vliw_ptr, blist_t bnds, fence_t fence,
                int *pneed_stall)
{
  expr_t best;

  /* Choose the best insn for scheduling via:
     1) sorting the ready list based on priority;
     2) calling the reorder hook;
     3) calling max_issue.  */
  best = fill_ready_list (av_vliw_ptr, bnds, fence, pneed_stall);
  if (best == NULL && ready.n_ready > 0)
    {
      int privileged_n, index;

      can_issue_more = invoke_reorder_hooks (fence);
      if (can_issue_more > 0)
        {
          /* Try choosing the best insn until we find one that is could be
             scheduled due to liveness restrictions on its destination register.
             In the future, we'd like to choose once and then just probe insns
             in the order of their priority.  */
          invoke_dfa_lookahead_guard ();
          privileged_n = calculate_privileged_insns ();
          can_issue_more = choose_best_insn (fence, privileged_n, &index);
          if (can_issue_more)
            best = find_expr_for_ready (index, true);
        }
      /* We had some available insns, so if we can't issue them,
         we have a stall.  */
      if (can_issue_more == 0)
        {
          best = NULL;
          *pneed_stall = 1;
        }
    }

  if (best != NULL)
    {
      can_issue_more = invoke_aftermath_hooks (fence, EXPR_INSN_RTX (best),
                                               can_issue_more);
      if (targetm.sched.variable_issue
	  && can_issue_more == 0)
        *pneed_stall = 1;
    }

  if (sched_verbose >= 2)
    {
      if (best != NULL)
        {
          sel_print ("Best expression (vliw form): ");
          dump_expr (best);
          sel_print ("; cycle %d\n", FENCE_CYCLE (fence));
        }
      else
        sel_print ("No best expr found!\n");
    }

  return best;
}


/* Functions that implement the core of the scheduler.  */


/* Emit an instruction from EXPR with SEQNO and VINSN after
   PLACE_TO_INSERT.  */
static insn_t
emit_insn_from_expr_after (expr_t expr, vinsn_t vinsn, int seqno,
                           insn_t place_to_insert)
{
  /* This assert fails when we have identical instructions
     one of which dominates the other.  In this case move_op ()
     finds the first instruction and doesn't search for second one.
     The solution would be to compute av_set after the first found
     insn and, if insn present in that set, continue searching.
     For now we workaround this issue in move_op.  */
  gcc_assert (!INSN_IN_STREAM_P (EXPR_INSN_RTX (expr)));

  if (EXPR_WAS_RENAMED (expr))
    {
      unsigned regno = expr_dest_regno (expr);

      if (HARD_REGISTER_NUM_P (regno))
	{
	  df_set_regs_ever_live (regno, true);
	  reg_rename_tick[regno] = ++reg_rename_this_tick;
	}
    }

  return sel_gen_insn_from_expr_after (expr, vinsn, seqno,
                                       place_to_insert);
}

/* Return TRUE if BB can hold bookkeeping code.  */
static bool
block_valid_for_bookkeeping_p (basic_block bb)
{
  insn_t bb_end = BB_END (bb);

  if (!in_current_region_p (bb) || EDGE_COUNT (bb->succs) > 1)
    return false;

  if (INSN_P (bb_end))
    {
      if (INSN_SCHED_TIMES (bb_end) > 0)
	return false;
    }
  else
    gcc_assert (NOTE_INSN_BASIC_BLOCK_P (bb_end));

  return true;
}

/* Attempt to find a block that can hold bookkeeping code for path(s) incoming
   into E2->dest, except from E1->src (there may be a sequence of empty basic
   blocks between E1->src and E2->dest).  Return found block, or NULL if new
   one must be created.  If LAX holds, don't assume there is a simple path
   from E1->src to E2->dest.  */
static basic_block
find_block_for_bookkeeping (edge e1, edge e2, bool lax)
{
  basic_block candidate_block = NULL;
  edge e;

  /* Loop over edges from E1 to E2, inclusive.  */
  for (e = e1; !lax || e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun); e =
       EDGE_SUCC (e->dest, 0))
    {
      if (EDGE_COUNT (e->dest->preds) == 2)
	{
	  if (candidate_block == NULL)
	    candidate_block = (EDGE_PRED (e->dest, 0) == e
			       ? EDGE_PRED (e->dest, 1)->src
			       : EDGE_PRED (e->dest, 0)->src);
	  else
	    /* Found additional edge leading to path from e1 to e2
	       from aside.  */
	    return NULL;
	}
      else if (EDGE_COUNT (e->dest->preds) > 2)
	/* Several edges leading to path from e1 to e2 from aside.  */
	return NULL;

      if (e == e2)
	return ((!lax || candidate_block)
		&& block_valid_for_bookkeeping_p (candidate_block)
		? candidate_block
		: NULL);

      if (lax && EDGE_COUNT (e->dest->succs) != 1)
	return NULL;
    }

  if (lax)
    return NULL;

  gcc_unreachable ();
}

/* Create new basic block for bookkeeping code for path(s) incoming into
   E2->dest, except from E1->src.  Return created block.  */
static basic_block
create_block_for_bookkeeping (edge e1, edge e2)
{
  basic_block new_bb, bb = e2->dest;

  /* Check that we don't spoil the loop structure.  */
  if (current_loop_nest)
    {
      basic_block latch = current_loop_nest->latch;

      /* We do not split header.  */
      gcc_assert (e2->dest != current_loop_nest->header);

      /* We do not redirect the only edge to the latch block.  */
      gcc_assert (e1->dest != latch
		  || !single_pred_p (latch)
		  || e1 != single_pred_edge (latch));
    }

  /* Split BB to insert BOOK_INSN there.  */
  new_bb = sched_split_block (bb, NULL);

  /* Move note_list from the upper bb.  */
  gcc_assert (BB_NOTE_LIST (new_bb) == NULL_RTX);
  BB_NOTE_LIST (new_bb) = BB_NOTE_LIST (bb);
  BB_NOTE_LIST (bb) = NULL;

  gcc_assert (e2->dest == bb);

  /* Skip block for bookkeeping copy when leaving E1->src.  */
  if (e1->flags & EDGE_FALLTHRU)
    sel_redirect_edge_and_branch_force (e1, new_bb);
  else
    sel_redirect_edge_and_branch (e1, new_bb);

  gcc_assert (e1->dest == new_bb);
  gcc_assert (sel_bb_empty_p (bb));

  /* To keep basic block numbers in sync between debug and non-debug
     compilations, we have to rotate blocks here.  Consider that we
     started from (a,b)->d, (c,d)->e, and d contained only debug
     insns.  It would have been removed before if the debug insns
     weren't there, so we'd have split e rather than d.  So what we do
     now is to swap the block numbers of new_bb and
     single_succ(new_bb) == e, so that the insns that were in e before
     get the new block number.  */

  if (MAY_HAVE_DEBUG_INSNS)
    {
      basic_block succ;
      insn_t insn = sel_bb_head (new_bb);
      insn_t last;

      if (DEBUG_INSN_P (insn)
	  && single_succ_p (new_bb)
	  && (succ = single_succ (new_bb))
	  && succ != EXIT_BLOCK_PTR_FOR_FN (cfun)
	  && DEBUG_INSN_P ((last = sel_bb_end (new_bb))))
	{
	  while (insn != last && (DEBUG_INSN_P (insn) || NOTE_P (insn)))
	    insn = NEXT_INSN (insn);

	  if (insn == last)
	    {
	      sel_global_bb_info_def gbi;
	      sel_region_bb_info_def rbi;

	      if (sched_verbose >= 2)
		sel_print ("Swapping block ids %i and %i\n",
			   new_bb->index, succ->index);

	      std::swap (new_bb->index, succ->index);

	      SET_BASIC_BLOCK_FOR_FN (cfun, new_bb->index, new_bb);
	      SET_BASIC_BLOCK_FOR_FN (cfun, succ->index, succ);

	      memcpy (&gbi, SEL_GLOBAL_BB_INFO (new_bb), sizeof (gbi));
	      memcpy (SEL_GLOBAL_BB_INFO (new_bb), SEL_GLOBAL_BB_INFO (succ),
		      sizeof (gbi));
	      memcpy (SEL_GLOBAL_BB_INFO (succ), &gbi, sizeof (gbi));

	      memcpy (&rbi, SEL_REGION_BB_INFO (new_bb), sizeof (rbi));
	      memcpy (SEL_REGION_BB_INFO (new_bb), SEL_REGION_BB_INFO (succ),
		      sizeof (rbi));
	      memcpy (SEL_REGION_BB_INFO (succ), &rbi, sizeof (rbi));

	      std::swap (BLOCK_TO_BB (new_bb->index),
			 BLOCK_TO_BB (succ->index));

	      std::swap (CONTAINING_RGN (new_bb->index),
			 CONTAINING_RGN (succ->index));

	      for (int i = 0; i < current_nr_blocks; i++)
		if (BB_TO_BLOCK (i) == succ->index)
		  BB_TO_BLOCK (i) = new_bb->index;
		else if (BB_TO_BLOCK (i) == new_bb->index)
		  BB_TO_BLOCK (i) = succ->index;

	      FOR_BB_INSNS (new_bb, insn)
		if (INSN_P (insn))
		  EXPR_ORIG_BB_INDEX (INSN_EXPR (insn)) = new_bb->index;

	      FOR_BB_INSNS (succ, insn)
		if (INSN_P (insn))
		  EXPR_ORIG_BB_INDEX (INSN_EXPR (insn)) = succ->index;

	      if (bitmap_clear_bit (code_motion_visited_blocks, new_bb->index))
		bitmap_set_bit (code_motion_visited_blocks, succ->index);

	      gcc_assert (LABEL_P (BB_HEAD (new_bb))
			  && LABEL_P (BB_HEAD (succ)));

	      if (sched_verbose >= 4)
		sel_print ("Swapping code labels %i and %i\n",
			   CODE_LABEL_NUMBER (BB_HEAD (new_bb)),
			   CODE_LABEL_NUMBER (BB_HEAD (succ)));

	      std::swap (CODE_LABEL_NUMBER (BB_HEAD (new_bb)),
			 CODE_LABEL_NUMBER (BB_HEAD (succ)));
	    }
	}
    }

  return bb;
}

/* Return insn after which we must insert bookkeeping code for path(s) incoming
   into E2->dest, except from E1->src.  If the returned insn immediately
   precedes a fence, assign that fence to *FENCE_TO_REWIND.  */
static insn_t
find_place_for_bookkeeping (edge e1, edge e2, fence_t *fence_to_rewind)
{
  insn_t place_to_insert;
  /* Find a basic block that can hold bookkeeping.  If it can be found, do not
     create new basic block, but insert bookkeeping there.  */
  basic_block book_block = find_block_for_bookkeeping (e1, e2, FALSE);

  if (book_block)
    {
      place_to_insert = BB_END (book_block);

      /* Don't use a block containing only debug insns for
	 bookkeeping, this causes scheduling differences between debug
	 and non-debug compilations, for the block would have been
	 removed already.  */
      if (DEBUG_INSN_P (place_to_insert))
	{
	  rtx_insn *insn = sel_bb_head (book_block);

	  while (insn != place_to_insert &&
		 (DEBUG_INSN_P (insn) || NOTE_P (insn)))
	    insn = NEXT_INSN (insn);

	  if (insn == place_to_insert)
	    book_block = NULL;
	}
    }

  if (!book_block)
    {
      book_block = create_block_for_bookkeeping (e1, e2);
      place_to_insert = BB_END (book_block);
      if (sched_verbose >= 9)
	sel_print ("New block is %i, split from bookkeeping block %i\n",
		   EDGE_SUCC (book_block, 0)->dest->index, book_block->index);
    }
  else
    {
      if (sched_verbose >= 9)
	sel_print ("Pre-existing bookkeeping block is %i\n", book_block->index);
    }

  *fence_to_rewind = NULL;
  /* If basic block ends with a jump, insert bookkeeping code right before it.
     Notice if we are crossing a fence when taking PREV_INSN.  */
  if (INSN_P (place_to_insert) && control_flow_insn_p (place_to_insert))
    {
      *fence_to_rewind = flist_lookup (fences, place_to_insert);
      place_to_insert = PREV_INSN (place_to_insert);
    }

  return place_to_insert;
}

/* Find a proper seqno for bookkeeing insn inserted at PLACE_TO_INSERT
   for JOIN_POINT.   */
static int
find_seqno_for_bookkeeping (insn_t place_to_insert, insn_t join_point)
{
  int seqno;

  /* Check if we are about to insert bookkeeping copy before a jump, and use
     jump's seqno for the copy; otherwise, use JOIN_POINT's seqno.  */
  rtx_insn *next = NEXT_INSN (place_to_insert);
  if (INSN_P (next)
      && JUMP_P (next)
      && BLOCK_FOR_INSN (next) == BLOCK_FOR_INSN (place_to_insert))
    {
      gcc_assert (INSN_SCHED_TIMES (next) == 0);
      seqno = INSN_SEQNO (next);
    }
  else if (INSN_SEQNO (join_point) > 0)
    seqno = INSN_SEQNO (join_point);
  else
    {
      seqno = get_seqno_by_preds (place_to_insert);

      /* Sometimes the fences can move in such a way that there will be
         no instructions with positive seqno around this bookkeeping.
         This means that there will be no way to get to it by a regular
         fence movement.  Never mind because we pick up such pieces for
         rescheduling anyways, so any positive value will do for now.  */
      if (seqno < 0)
        {
          gcc_assert (pipelining_p);
          seqno = 1;
        }
    }

  gcc_assert (seqno > 0);
  return seqno;
}

/* Insert bookkeeping copy of C_EXPS's insn after PLACE_TO_INSERT, assigning
   NEW_SEQNO to it.  Return created insn.  */
static insn_t
emit_bookkeeping_insn (insn_t place_to_insert, expr_t c_expr, int new_seqno)
{
  rtx_insn *new_insn_rtx = create_copy_of_insn_rtx (EXPR_INSN_RTX (c_expr));

  vinsn_t new_vinsn
    = create_vinsn_from_insn_rtx (new_insn_rtx,
				  VINSN_UNIQUE_P (EXPR_VINSN (c_expr)));

  insn_t new_insn = emit_insn_from_expr_after (c_expr, new_vinsn, new_seqno,
					       place_to_insert);

  INSN_SCHED_TIMES (new_insn) = 0;
  bitmap_set_bit (current_copies, INSN_UID (new_insn));

  return new_insn;
}

/* Generate a bookkeeping copy of C_EXPR's insn for path(s) incoming into to
   E2->dest, except from E1->src (there may be a sequence of empty blocks
   between E1->src and E2->dest).  Return block containing the copy.
   All scheduler data is initialized for the newly created insn.  */
static basic_block
generate_bookkeeping_insn (expr_t c_expr, edge e1, edge e2)
{
  insn_t join_point, place_to_insert, new_insn;
  int new_seqno;
  bool need_to_exchange_data_sets;
  fence_t fence_to_rewind;

  if (sched_verbose >= 4)
    sel_print ("Generating bookkeeping insn (%d->%d)\n", e1->src->index,
	       e2->dest->index);

  join_point = sel_bb_head (e2->dest);
  place_to_insert = find_place_for_bookkeeping (e1, e2, &fence_to_rewind);
  new_seqno = find_seqno_for_bookkeeping (place_to_insert, join_point);
  need_to_exchange_data_sets
    = sel_bb_empty_p (BLOCK_FOR_INSN (place_to_insert));

  new_insn = emit_bookkeeping_insn (place_to_insert, c_expr, new_seqno);

  if (fence_to_rewind)
    FENCE_INSN (fence_to_rewind) = new_insn;

  /* When inserting bookkeeping insn in new block, av sets should be
     following: old basic block (that now holds bookkeeping) data sets are
     the same as was before generation of bookkeeping, and new basic block
     (that now hold all other insns of old basic block) data sets are
     invalid.  So exchange data sets for these basic blocks as sel_split_block
     mistakenly exchanges them in this case.  Cannot do it earlier because
     when single instruction is added to new basic block it should hold NULL
     lv_set.  */
  if (need_to_exchange_data_sets)
    exchange_data_sets (BLOCK_FOR_INSN (new_insn),
			BLOCK_FOR_INSN (join_point));

  stat_bookkeeping_copies++;
  return BLOCK_FOR_INSN (new_insn);
}

/* Remove from AV_PTR all insns that may need bookkeeping when scheduling
   on FENCE, but we are unable to copy them.  */
static void
remove_insns_that_need_bookkeeping (fence_t fence, av_set_t *av_ptr)
{
  expr_t expr;
  av_set_iterator i;

  /*  An expression does not need bookkeeping if it is available on all paths
      from current block to original block and current block dominates
      original block.  We check availability on all paths by examining
      EXPR_SPEC; this is not equivalent, because it may be positive even
      if expr is available on all paths (but if expr is not available on
      any path, EXPR_SPEC will be positive).  */

  FOR_EACH_EXPR_1 (expr, i, av_ptr)
    {
      if (!control_flow_insn_p (EXPR_INSN_RTX (expr))
	  && (!bookkeeping_p || VINSN_UNIQUE_P (EXPR_VINSN (expr)))
	  && (EXPR_SPEC (expr)
	      || !EXPR_ORIG_BB_INDEX (expr)
	      || !dominated_by_p (CDI_DOMINATORS,
				  BASIC_BLOCK_FOR_FN (cfun,
						      EXPR_ORIG_BB_INDEX (expr)),
				  BLOCK_FOR_INSN (FENCE_INSN (fence)))))
	{
          if (sched_verbose >= 4)
            sel_print ("Expr %d removed because it would need bookkeeping, which "
                       "cannot be created\n", INSN_UID (EXPR_INSN_RTX (expr)));
	  av_set_iter_remove (&i);
	}
    }
}

/* Moving conditional jump through some instructions.

   Consider example:

       ...                     <- current scheduling point
       NOTE BASIC BLOCK:       <- bb header
       (p8)  add r14=r14+0x9;;
       (p8)  mov [r14]=r23
       (!p8) jump L1;;
       NOTE BASIC BLOCK:
       ...

   We can schedule jump one cycle earlier, than mov, because they cannot be
   executed together as their predicates are mutually exclusive.

   This is done in this way: first, new fallthrough basic block is created
   after jump (it is always can be done, because there already should be a
   fallthrough block, where control flow goes in case of predicate being true -
   in our example; otherwise there should be a dependence between those
   instructions and jump and we cannot schedule jump right now);
   next, all instructions between jump and current scheduling point are moved
   to this new block.  And the result is this:

      NOTE BASIC BLOCK:
      (!p8) jump L1           <- current scheduling point
      NOTE BASIC BLOCK:       <- bb header
      (p8)  add r14=r14+0x9;;
      (p8)  mov [r14]=r23
      NOTE BASIC BLOCK:
      ...
*/
static void
move_cond_jump (rtx_insn *insn, bnd_t bnd)
{
  edge ft_edge;
  basic_block block_from, block_next, block_new, block_bnd, bb;
  rtx_insn *next, *prev, *link, *head;

  block_from = BLOCK_FOR_INSN (insn);
  block_bnd = BLOCK_FOR_INSN (BND_TO (bnd));
  prev = BND_TO (bnd);

  /* Moving of jump should not cross any other jumps or beginnings of new
     basic blocks.  The only exception is when we move a jump through
     mutually exclusive insns along fallthru edges.  */
  if (flag_checking && block_from != block_bnd)
    {
      bb = block_from;
      for (link = PREV_INSN (insn); link != PREV_INSN (prev);
           link = PREV_INSN (link))
        {
          if (INSN_P (link))
            gcc_assert (sched_insns_conditions_mutex_p (insn, link));
          if (BLOCK_FOR_INSN (link) && BLOCK_FOR_INSN (link) != bb)
            {
              gcc_assert (single_pred (bb) == BLOCK_FOR_INSN (link));
              bb = BLOCK_FOR_INSN (link);
            }
        }
    }

  /* Jump is moved to the boundary.  */
  next = PREV_INSN (insn);
  BND_TO (bnd) = insn;

  ft_edge = find_fallthru_edge_from (block_from);
  block_next = ft_edge->dest;
  /* There must be a fallthrough block (or where should go
  control flow in case of false jump predicate otherwise?).  */
  gcc_assert (block_next);

  /* Create new empty basic block after source block.  */
  block_new = sel_split_edge (ft_edge);
  gcc_assert (block_new->next_bb == block_next
              && block_from->next_bb == block_new);

  /* Move all instructions except INSN to BLOCK_NEW.  */
  bb = block_bnd;
  head = BB_HEAD (block_new);
  while (bb != block_from->next_bb)
    {
      rtx_insn *from, *to;
      from = bb == block_bnd ? prev : sel_bb_head (bb);
      to = bb == block_from ? next : sel_bb_end (bb);

      /* The jump being moved can be the first insn in the block.
         In this case we don't have to move anything in this block.  */
      if (NEXT_INSN (to) != from)
        {
          reorder_insns (from, to, head);

          for (link = to; link != head; link = PREV_INSN (link))
            EXPR_ORIG_BB_INDEX (INSN_EXPR (link)) = block_new->index;
          head = to;
        }

      /* Cleanup possibly empty blocks left.  */
      block_next = bb->next_bb;
      if (bb != block_from)
	tidy_control_flow (bb, false);
      bb = block_next;
    }

  /* Assert there is no jump to BLOCK_NEW, only fallthrough edge.  */
  gcc_assert (NOTE_INSN_BASIC_BLOCK_P (BB_HEAD (block_new)));

  gcc_assert (!sel_bb_empty_p (block_from)
              && !sel_bb_empty_p (block_new));

  /* Update data sets for BLOCK_NEW to represent that INSN and
     instructions from the other branch of INSN is no longer
     available at BLOCK_NEW.  */
  BB_AV_LEVEL (block_new) = global_level;
  gcc_assert (BB_LV_SET (block_new) == NULL);
  BB_LV_SET (block_new) = get_clear_regset_from_pool ();
  update_data_sets (sel_bb_head (block_new));

  /* INSN is a new basic block header - so prepare its data
     structures and update availability and liveness sets.  */
  update_data_sets (insn);

  if (sched_verbose >= 4)
    sel_print ("Moving jump %d\n", INSN_UID (insn));
}

/* Remove nops generated during move_op for preventing removal of empty
   basic blocks.  */
static void
remove_temp_moveop_nops (bool full_tidying)
{
  int i;
  insn_t insn;

  FOR_EACH_VEC_ELT (vec_temp_moveop_nops, i, insn)
    {
      gcc_assert (INSN_NOP_P (insn));
      return_nop_to_pool (insn, full_tidying);
    }

  /* Empty the vector.  */
  if (vec_temp_moveop_nops.length () > 0)
    vec_temp_moveop_nops.block_remove (0, vec_temp_moveop_nops.length ());
}

/* Records the maximal UID before moving up an instruction.  Used for
   distinguishing between bookkeeping copies and original insns.  */
static int max_uid_before_move_op = 0;

/* When true, we're always scheduling next insn on the already scheduled code
   to get the right insn data for the following bundling or other passes.  */
static int force_next_insn = 0;

/* Remove from AV_VLIW_P all instructions but next when debug counter
   tells us so.  Next instruction is fetched from BNDS.  */
static void
remove_insns_for_debug (blist_t bnds, av_set_t *av_vliw_p)
{
  if (! dbg_cnt (sel_sched_insn_cnt) || force_next_insn)
    /* Leave only the next insn in av_vliw.  */
    {
      av_set_iterator av_it;
      expr_t expr;
      bnd_t bnd = BLIST_BND (bnds);
      insn_t next = BND_TO (bnd);

      gcc_assert (BLIST_NEXT (bnds) == NULL);

      FOR_EACH_EXPR_1 (expr, av_it, av_vliw_p)
        if (EXPR_INSN_RTX (expr) != next)
          av_set_iter_remove (&av_it);
    }
}

/* Compute available instructions on BNDS.  FENCE is the current fence.  Write
   the computed set to *AV_VLIW_P.  */
static void
compute_av_set_on_boundaries (fence_t fence, blist_t bnds, av_set_t *av_vliw_p)
{
  if (sched_verbose >= 2)
    {
      sel_print ("Boundaries: ");
      dump_blist (bnds);
      sel_print ("\n");
    }

  for (; bnds; bnds = BLIST_NEXT (bnds))
    {
      bnd_t bnd = BLIST_BND (bnds);
      av_set_t av1_copy;
      insn_t bnd_to = BND_TO (bnd);

      /* Rewind BND->TO to the basic block header in case some bookkeeping
         instructions were inserted before BND->TO and it needs to be
         adjusted.  */
      if (sel_bb_head_p (bnd_to))
        gcc_assert (INSN_SCHED_TIMES (bnd_to) == 0);
      else
        while (INSN_SCHED_TIMES (PREV_INSN (bnd_to)) == 0)
          {
            bnd_to = PREV_INSN (bnd_to);
            if (sel_bb_head_p (bnd_to))
              break;
          }

      if (BND_TO (bnd) != bnd_to)
	{
  	  gcc_assert (FENCE_INSN (fence) == BND_TO (bnd));
	  FENCE_INSN (fence) = bnd_to;
	  BND_TO (bnd) = bnd_to;
	}

      av_set_clear (&BND_AV (bnd));
      BND_AV (bnd) = compute_av_set (BND_TO (bnd), NULL, 0, true);

      av_set_clear (&BND_AV1 (bnd));
      BND_AV1 (bnd) = av_set_copy (BND_AV (bnd));

      moveup_set_inside_insn_group (&BND_AV1 (bnd), NULL);

      av1_copy = av_set_copy (BND_AV1 (bnd));
      av_set_union_and_clear (av_vliw_p, &av1_copy, NULL);
    }

  if (sched_verbose >= 2)
    {
      sel_print ("Available exprs (vliw form): ");
      dump_av_set (*av_vliw_p);
      sel_print ("\n");
    }
}

/* Calculate the sequential av set on BND corresponding to the EXPR_VLIW
   expression.  When FOR_MOVEOP is true, also replace the register of
   expressions found with the register from EXPR_VLIW.  */
static av_set_t
find_sequential_best_exprs (bnd_t bnd, expr_t expr_vliw, bool for_moveop)
{
  av_set_t expr_seq = NULL;
  expr_t expr;
  av_set_iterator i;

  FOR_EACH_EXPR (expr, i, BND_AV (bnd))
    {
      if (equal_after_moveup_path_p (expr, NULL, expr_vliw))
        {
          if (for_moveop)
            {
              /* The sequential expression has the right form to pass
                 to move_op except when renaming happened.  Put the
                 correct register in EXPR then.  */
              if (EXPR_SEPARABLE_P (expr) && REG_P (EXPR_LHS (expr)))
		{
                  if (expr_dest_regno (expr) != expr_dest_regno (expr_vliw))
		    {
		      replace_dest_with_reg_in_expr (expr, EXPR_LHS (expr_vliw));
		      stat_renamed_scheduled++;
		    }
		  /* Also put the correct TARGET_AVAILABLE bit on the expr.
                     This is needed when renaming came up with original
                     register.  */
                  else if (EXPR_TARGET_AVAILABLE (expr)
                           != EXPR_TARGET_AVAILABLE (expr_vliw))
		    {
		      gcc_assert (EXPR_TARGET_AVAILABLE (expr_vliw) == 1);
		      EXPR_TARGET_AVAILABLE (expr) = 1;
		    }
		}
              if (EXPR_WAS_SUBSTITUTED (expr))
                stat_substitutions_total++;
            }

          av_set_add (&expr_seq, expr);

          /* With substitution inside insn group, it is possible
             that more than one expression in expr_seq will correspond
             to expr_vliw.  In this case, choose one as the attempt to
             move both leads to miscompiles.  */
          break;
        }
    }

  if (for_moveop && sched_verbose >= 2)
    {
      sel_print ("Best expression(s) (sequential form): ");
      dump_av_set (expr_seq);
      sel_print ("\n");
    }

  return expr_seq;
}


/* Move nop to previous block.  */
static void ATTRIBUTE_UNUSED
move_nop_to_previous_block (insn_t nop, basic_block prev_bb)
{
  insn_t prev_insn, next_insn;

  gcc_assert (sel_bb_head_p (nop)
              && prev_bb == BLOCK_FOR_INSN (nop)->prev_bb);
  rtx_note *note = bb_note (BLOCK_FOR_INSN (nop));
  prev_insn = sel_bb_end (prev_bb);
  next_insn = NEXT_INSN (nop);
  gcc_assert (prev_insn != NULL_RTX
              && PREV_INSN (note) == prev_insn);

  SET_NEXT_INSN (prev_insn) = nop;
  SET_PREV_INSN (nop) = prev_insn;

  SET_PREV_INSN (note) = nop;
  SET_NEXT_INSN (note) = next_insn;

  SET_NEXT_INSN (nop) = note;
  SET_PREV_INSN (next_insn) = note;

  BB_END (prev_bb) = nop;
  BLOCK_FOR_INSN (nop) = prev_bb;
}

/* Prepare a place to insert the chosen expression on BND.  */
static insn_t
prepare_place_to_insert (bnd_t bnd)
{
  insn_t place_to_insert;

  /* Init place_to_insert before calling move_op, as the later
     can possibly remove BND_TO (bnd).  */
  if (/* If this is not the first insn scheduled.  */
      BND_PTR (bnd))
    {
      /* Add it after last scheduled.  */
      place_to_insert = ILIST_INSN (BND_PTR (bnd));
      if (DEBUG_INSN_P (place_to_insert))
	{
	  ilist_t l = BND_PTR (bnd);
	  while ((l = ILIST_NEXT (l)) &&
		 DEBUG_INSN_P (ILIST_INSN (l)))
	    ;
	  if (!l)
	    place_to_insert = NULL;
	}
    }
  else
    place_to_insert = NULL;

  if (!place_to_insert)
    {
      /* Add it before BND_TO.  The difference is in the
         basic block, where INSN will be added.  */
      place_to_insert = get_nop_from_pool (BND_TO (bnd));
      gcc_assert (BLOCK_FOR_INSN (place_to_insert)
                  == BLOCK_FOR_INSN (BND_TO (bnd)));
    }

  return place_to_insert;
}

/* Find original instructions for EXPR_SEQ and move it to BND boundary.
   Return the expression to emit in C_EXPR.  */
static bool
move_exprs_to_boundary (bnd_t bnd, expr_t expr_vliw,
                        av_set_t expr_seq, expr_t c_expr)
{
  bool b, should_move;
  unsigned book_uid;
  bitmap_iterator bi;
  int n_bookkeeping_copies_before_moveop;

  /* Make a move.  This call will remove the original operation,
     insert all necessary bookkeeping instructions and update the
     data sets.  After that all we have to do is add the operation
     at before BND_TO (BND).  */
  n_bookkeeping_copies_before_moveop = stat_bookkeeping_copies;
  max_uid_before_move_op = get_max_uid ();
  bitmap_clear (current_copies);
  bitmap_clear (current_originators);

  b = move_op (BND_TO (bnd), expr_seq, expr_vliw,
               get_dest_from_orig_ops (expr_seq), c_expr, &should_move);

  /* We should be able to find the expression we've chosen for
     scheduling.  */
  gcc_assert (b);

  if (stat_bookkeeping_copies > n_bookkeeping_copies_before_moveop)
    stat_insns_needed_bookkeeping++;

  EXECUTE_IF_SET_IN_BITMAP (current_copies, 0, book_uid, bi)
    {
      unsigned uid;
      bitmap_iterator bi;

      /* We allocate these bitmaps lazily.  */
      if (! INSN_ORIGINATORS_BY_UID (book_uid))
        INSN_ORIGINATORS_BY_UID (book_uid) = BITMAP_ALLOC (NULL);

      bitmap_copy (INSN_ORIGINATORS_BY_UID (book_uid),
                   current_originators);

      /* Transitively add all originators' originators.  */
      EXECUTE_IF_SET_IN_BITMAP (current_originators, 0, uid, bi)
       if (INSN_ORIGINATORS_BY_UID (uid))
	 bitmap_ior_into (INSN_ORIGINATORS_BY_UID (book_uid),
			  INSN_ORIGINATORS_BY_UID (uid));
    }

  return should_move;
}


/* Debug a DFA state as an array of bytes.  */
static void
debug_state (state_t state)
{
  unsigned char *p;
  unsigned int i, size = dfa_state_size;

  sel_print ("state (%u):", size);
  for (i = 0, p = (unsigned char *) state; i < size; i++)
    sel_print (" %d", p[i]);
  sel_print ("\n");
}

/* Advance state on FENCE with INSN.  Return true if INSN is
   an ASM, and we should advance state once more.  */
static bool
advance_state_on_fence (fence_t fence, insn_t insn)
{
  bool asm_p;

  if (recog_memoized (insn) >= 0)
    {
      int res;
      state_t temp_state = alloca (dfa_state_size);

      gcc_assert (!INSN_ASM_P (insn));
      asm_p = false;

      memcpy (temp_state, FENCE_STATE (fence), dfa_state_size);
      res = state_transition (FENCE_STATE (fence), insn);
      gcc_assert (res < 0);

      if (memcmp (temp_state, FENCE_STATE (fence), dfa_state_size))
        {
          FENCE_ISSUED_INSNS (fence)++;

          /* We should never issue more than issue_rate insns.  */
          if (FENCE_ISSUED_INSNS (fence) > issue_rate)
            gcc_unreachable ();
        }
    }
  else
    {
      /* This could be an ASM insn which we'd like to schedule
         on the next cycle.  */
      asm_p = INSN_ASM_P (insn);
      if (!FENCE_STARTS_CYCLE_P (fence) && asm_p)
        advance_one_cycle (fence);
    }

  if (sched_verbose >= 2)
    debug_state (FENCE_STATE (fence));
  if (!DEBUG_INSN_P (insn))
    FENCE_STARTS_CYCLE_P (fence) = 0;
  FENCE_ISSUE_MORE (fence) = can_issue_more;
  return asm_p;
}

/* Update FENCE on which INSN was scheduled and this INSN, too.  NEED_STALL
   is nonzero if we need to stall after issuing INSN.  */
static void
update_fence_and_insn (fence_t fence, insn_t insn, int need_stall)
{
  bool asm_p;

  /* First, reflect that something is scheduled on this fence.  */
  asm_p = advance_state_on_fence (fence, insn);
  FENCE_LAST_SCHEDULED_INSN (fence) = insn;
  vec_safe_push (FENCE_EXECUTING_INSNS (fence), insn);
  if (SCHED_GROUP_P (insn))
    {
      FENCE_SCHED_NEXT (fence) = INSN_SCHED_NEXT (insn);
      SCHED_GROUP_P (insn) = 0;
    }
  else
    FENCE_SCHED_NEXT (fence) = NULL;
  if (INSN_UID (insn) < FENCE_READY_TICKS_SIZE (fence))
    FENCE_READY_TICKS (fence) [INSN_UID (insn)] = 0;

  /* Set instruction scheduling info.  This will be used in bundling,
     pipelining, tick computations etc.  */
  ++INSN_SCHED_TIMES (insn);
  EXPR_TARGET_AVAILABLE (INSN_EXPR (insn)) = true;
  EXPR_ORIG_SCHED_CYCLE (INSN_EXPR (insn)) = FENCE_CYCLE (fence);
  INSN_AFTER_STALL_P (insn) = FENCE_AFTER_STALL_P (fence);
  INSN_SCHED_CYCLE (insn) = FENCE_CYCLE (fence);

  /* This does not account for adjust_cost hooks, just add the biggest
     constant the hook may add to the latency.  TODO: make this
     a target dependent constant.  */
  INSN_READY_CYCLE (insn)
    = INSN_SCHED_CYCLE (insn) + (INSN_CODE (insn) < 0
                                 ? 1
                                 : maximal_insn_latency (insn) + 1);

  /* Change these fields last, as they're used above.  */
  FENCE_AFTER_STALL_P (fence) = 0;
  if (asm_p || need_stall)
    advance_one_cycle (fence);

  /* Indicate that we've scheduled something on this fence.  */
  FENCE_SCHEDULED_P (fence) = true;
  scheduled_something_on_previous_fence = true;

  /* Print debug information when insn's fields are updated.  */
  if (sched_verbose >= 2)
    {
      sel_print ("Scheduling insn: ");
      dump_insn_1 (insn, 1);
      sel_print ("\n");
    }
}

/* Update boundary BND (and, if needed, FENCE) with INSN, remove the
   old boundary from BNDSP, add new boundaries to BNDS_TAIL_P and
   return it.  */
static blist_t *
update_boundaries (fence_t fence, bnd_t bnd, insn_t insn, blist_t *bndsp,
                   blist_t *bnds_tailp)
{
  succ_iterator si;
  insn_t succ;

  advance_deps_context (BND_DC (bnd), insn);
  FOR_EACH_SUCC_1 (succ, si, insn,
                   SUCCS_NORMAL | SUCCS_SKIP_TO_LOOP_EXITS)
    {
      ilist_t ptr = ilist_copy (BND_PTR (bnd));

      ilist_add (&ptr, insn);

      if (DEBUG_INSN_P (insn) && sel_bb_end_p (insn)
	  && is_ineligible_successor (succ, ptr))
	{
	  ilist_clear (&ptr);
	  continue;
	}

      if (FENCE_INSN (fence) == insn && !sel_bb_end_p (insn))
	{
	  if (sched_verbose >= 9)
	    sel_print ("Updating fence insn from %i to %i\n",
		       INSN_UID (insn), INSN_UID (succ));
	  FENCE_INSN (fence) = succ;
	}
      blist_add (bnds_tailp, succ, ptr, BND_DC (bnd));
      bnds_tailp = &BLIST_NEXT (*bnds_tailp);
    }

  blist_remove (bndsp);
  return bnds_tailp;
}

/* Schedule EXPR_VLIW on BND.  Return the insn emitted.  */
static insn_t
schedule_expr_on_boundary (bnd_t bnd, expr_t expr_vliw, int seqno)
{
  av_set_t expr_seq;
  expr_t c_expr = XALLOCA (expr_def);
  insn_t place_to_insert;
  insn_t insn;
  bool should_move;

  expr_seq = find_sequential_best_exprs (bnd, expr_vliw, true);

  /* In case of scheduling a jump skipping some other instructions,
     prepare CFG.  After this, jump is at the boundary and can be
     scheduled as usual insn by MOVE_OP.  */
  if (vinsn_cond_branch_p (EXPR_VINSN (expr_vliw)))
    {
      insn = EXPR_INSN_RTX (expr_vliw);

      /* Speculative jumps are not handled.  */
      if (insn != BND_TO (bnd)
          && !sel_insn_is_speculation_check (insn))
        move_cond_jump (insn, bnd);
    }

  /* Find a place for C_EXPR to schedule.  */
  place_to_insert = prepare_place_to_insert (bnd);
  should_move = move_exprs_to_boundary (bnd, expr_vliw, expr_seq, c_expr);
  clear_expr (c_expr);

  /* Add the instruction.  The corner case to care about is when
     the expr_seq set has more than one expr, and we chose the one that
     is not equal to expr_vliw.  Then expr_vliw may be insn in stream, and
     we can't use it.  Generate the new vinsn.  */
  if (INSN_IN_STREAM_P (EXPR_INSN_RTX (expr_vliw)))
    {
      vinsn_t vinsn_new;

      vinsn_new = vinsn_copy (EXPR_VINSN (expr_vliw), false);
      change_vinsn_in_expr (expr_vliw, vinsn_new);
      should_move = false;
    }
  if (should_move)
    insn = sel_move_insn (expr_vliw, seqno, place_to_insert);
  else
    insn = emit_insn_from_expr_after (expr_vliw, NULL, seqno,
                                      place_to_insert);

  /* Return the nops generated for preserving of data sets back
     into pool.  */
  if (INSN_NOP_P (place_to_insert))
    return_nop_to_pool (place_to_insert, !DEBUG_INSN_P (insn));
  remove_temp_moveop_nops (!DEBUG_INSN_P (insn));

  av_set_clear (&expr_seq);

  /* Save the expression scheduled so to reset target availability if we'll
     meet it later on the same fence.  */
  if (EXPR_WAS_RENAMED (expr_vliw))
    vinsn_vec_add (&vec_target_unavailable_vinsns, INSN_EXPR (insn));

  /* Check that the recent movement didn't destroyed loop
     structure.  */
  gcc_assert (!pipelining_p
              || current_loop_nest == NULL
              || loop_latch_edge (current_loop_nest));
  return insn;
}

/* Stall for N cycles on FENCE.  */
static void
stall_for_cycles (fence_t fence, int n)
{
  int could_more;

  could_more = n > 1 || FENCE_ISSUED_INSNS (fence) < issue_rate;
  while (n--)
    advance_one_cycle (fence);
  if (could_more)
    FENCE_AFTER_STALL_P (fence) = 1;
}

/* Gather a parallel group of insns at FENCE and assign their seqno
   to SEQNO.  All scheduled insns are gathered in SCHEDULED_INSNS_TAILPP
   list for later recalculation of seqnos.  */
static void
fill_insns (fence_t fence, int seqno, ilist_t **scheduled_insns_tailpp)
{
  blist_t bnds = NULL, *bnds_tailp;
  av_set_t av_vliw = NULL;
  insn_t insn = FENCE_INSN (fence);

  if (sched_verbose >= 2)
    sel_print ("Starting fill_insns for insn %d, cycle %d\n",
               INSN_UID (insn), FENCE_CYCLE (fence));

  blist_add (&bnds, insn, NULL, FENCE_DC (fence));
  bnds_tailp = &BLIST_NEXT (bnds);
  set_target_context (FENCE_TC (fence));
  can_issue_more = FENCE_ISSUE_MORE (fence);
  target_bb = INSN_BB (insn);

  /* Do while we can add any operation to the current group.  */
  do
    {
      blist_t *bnds_tailp1, *bndsp;
      expr_t expr_vliw;
      int need_stall = false;
      int was_stall = 0, scheduled_insns = 0;
      int max_insns = pipelining_p ? issue_rate : 2 * issue_rate;
      int max_stall = pipelining_p ? 1 : 3;
      bool last_insn_was_debug = false;
      bool was_debug_bb_end_p = false;

      compute_av_set_on_boundaries (fence, bnds, &av_vliw);
      remove_insns_that_need_bookkeeping (fence, &av_vliw);
      remove_insns_for_debug (bnds, &av_vliw);

      /* Return early if we have nothing to schedule.  */
      if (av_vliw == NULL)
        break;

      /* Choose the best expression and, if needed, destination register
	 for it.  */
      do
        {
          expr_vliw = find_best_expr (&av_vliw, bnds, fence, &need_stall);
          if (! expr_vliw && need_stall)
            {
              /* All expressions required a stall.  Do not recompute av sets
                 as we'll get the same answer (modulo the insns between
                 the fence and its boundary, which will not be available for
                 pipelining).
		 If we are going to stall for too long, break to recompute av
		 sets and bring more insns for pipelining.  */
              was_stall++;
	      if (need_stall <= 3)
		stall_for_cycles (fence, need_stall);
	      else
		{
		  stall_for_cycles (fence, 1);
		  break;
		}
            }
        }
      while (! expr_vliw && need_stall);

      /* Now either we've selected expr_vliw or we have nothing to schedule.  */
      if (!expr_vliw)
        {
	  av_set_clear (&av_vliw);
          break;
        }

      bndsp = &bnds;
      bnds_tailp1 = bnds_tailp;

      do
	/* This code will be executed only once until we'd have several
           boundaries per fence.  */
        {
	  bnd_t bnd = BLIST_BND (*bndsp);

	  if (!av_set_is_in_p (BND_AV1 (bnd), EXPR_VINSN (expr_vliw)))
	    {
	      bndsp = &BLIST_NEXT (*bndsp);
	      continue;
	    }

          insn = schedule_expr_on_boundary (bnd, expr_vliw, seqno);
	  last_insn_was_debug = DEBUG_INSN_P (insn);
	  if (last_insn_was_debug)
	    was_debug_bb_end_p = (insn == BND_TO (bnd) && sel_bb_end_p (insn));
          update_fence_and_insn (fence, insn, need_stall);
          bnds_tailp = update_boundaries (fence, bnd, insn, bndsp, bnds_tailp);

	  /* Add insn to the list of scheduled on this cycle instructions.  */
	  ilist_add (*scheduled_insns_tailpp, insn);
	  *scheduled_insns_tailpp = &ILIST_NEXT (**scheduled_insns_tailpp);
        }
      while (*bndsp != *bnds_tailp1);

      av_set_clear (&av_vliw);
      if (!last_insn_was_debug)
	scheduled_insns++;

      /* We currently support information about candidate blocks only for
	 one 'target_bb' block.  Hence we can't schedule after jump insn,
	 as this will bring two boundaries and, hence, necessity to handle
	 information for two or more blocks concurrently.  */
      if ((last_insn_was_debug ? was_debug_bb_end_p : sel_bb_end_p (insn))
          || (was_stall
              && (was_stall >= max_stall
                  || scheduled_insns >= max_insns)))
        break;
    }
  while (bnds);

  gcc_assert (!FENCE_BNDS (fence));

  /* Update boundaries of the FENCE.  */
  while (bnds)
    {
      ilist_t ptr = BND_PTR (BLIST_BND (bnds));

      if (ptr)
	{
	  insn = ILIST_INSN (ptr);

	  if (!ilist_is_in_p (FENCE_BNDS (fence), insn))
	    ilist_add (&FENCE_BNDS (fence), insn);
	}

      blist_remove (&bnds);
    }

  /* Update target context on the fence.  */
  reset_target_context (FENCE_TC (fence), false);
}

/* All exprs in ORIG_OPS must have the same destination register or memory.
   Return that destination.  */
static rtx
get_dest_from_orig_ops (av_set_t orig_ops)
{
  rtx dest = NULL_RTX;
  av_set_iterator av_it;
  expr_t expr;
  bool first_p = true;

  FOR_EACH_EXPR (expr, av_it, orig_ops)
    {
      rtx x = EXPR_LHS (expr);

      if (first_p)
	{
	  first_p = false;
	  dest = x;
	}
      else
	gcc_assert (dest == x
		    || (dest != NULL_RTX && x != NULL_RTX
			&& rtx_equal_p (dest, x)));
    }

  return dest;
}

/* Update data sets for the bookkeeping block and record those expressions
   which become no longer available after inserting this bookkeeping.  */
static void
update_and_record_unavailable_insns (basic_block book_block)
{
  av_set_iterator i;
  av_set_t old_av_set = NULL;
  expr_t cur_expr;
  rtx_insn *bb_end = sel_bb_end (book_block);

  /* First, get correct liveness in the bookkeeping block.  The problem is
     the range between the bookeeping insn and the end of block.  */
  update_liveness_on_insn (bb_end);
  if (control_flow_insn_p (bb_end))
    update_liveness_on_insn (PREV_INSN (bb_end));

  /* If there's valid av_set on BOOK_BLOCK, then there might exist another
     fence above, where we may choose to schedule an insn which is
     actually blocked from moving up with the bookkeeping we create here.  */
  if (AV_SET_VALID_P (sel_bb_head (book_block)))
    {
      old_av_set = av_set_copy (BB_AV_SET (book_block));
      update_data_sets (sel_bb_head (book_block));

      /* Traverse all the expressions in the old av_set and check whether
	 CUR_EXPR is in new AV_SET.  */
      FOR_EACH_EXPR (cur_expr, i, old_av_set)
        {
          expr_t new_expr = av_set_lookup (BB_AV_SET (book_block),
					   EXPR_VINSN (cur_expr));

          if (! new_expr
              /* In this case, we can just turn off the E_T_A bit, but we can't
                 represent this information with the current vector.  */
              || EXPR_TARGET_AVAILABLE (new_expr)
		 != EXPR_TARGET_AVAILABLE (cur_expr))
	    /* Unfortunately, the below code could be also fired up on
	       separable insns, e.g. when moving insns through the new
	       speculation check as in PR 53701.  */
            vinsn_vec_add (&vec_bookkeeping_blocked_vinsns, cur_expr);
        }

      av_set_clear (&old_av_set);
    }
}

/* The main effect of this function is that sparams->c_expr is merged
   with (or copied to) lparams->c_expr_merged.  If there's only one successor,
   we avoid merging anything by copying sparams->c_expr to lparams->c_expr_merged.
   lparams->c_expr_merged is copied back to sparams->c_expr after all
   successors has been traversed.  lparams->c_expr_local is an expr allocated
   on stack in the caller function, and is used if there is more than one
   successor.

   SUCC is one of the SUCCS_NORMAL successors of INSN,
   MOVEOP_DRV_CALL_RES is the result of call code_motion_path_driver on succ,
   LPARAMS and STATIC_PARAMS contain the parameters described above.  */
static void
move_op_merge_succs (insn_t insn ATTRIBUTE_UNUSED,
                     insn_t succ ATTRIBUTE_UNUSED,
		     int moveop_drv_call_res,
		     cmpd_local_params_p lparams, void *static_params)
{
  moveop_static_params_p sparams = (moveop_static_params_p) static_params;

  /* Nothing to do, if original expr wasn't found below.  */
  if (moveop_drv_call_res != 1)
    return;

  /* If this is a first successor.  */
  if (!lparams->c_expr_merged)
    {
      lparams->c_expr_merged = sparams->c_expr;
      sparams->c_expr = lparams->c_expr_local;
    }
  else
    {
      /* We must merge all found expressions to get reasonable
	 EXPR_SPEC_DONE_DS for the resulting insn.  If we don't
	 do so then we can first find the expr with epsilon
	 speculation success probability and only then with the
	 good probability.  As a result the insn will get epsilon
	 probability and will never be scheduled because of
	 weakness_cutoff in find_best_expr.

	 We call merge_expr_data here instead of merge_expr
	 because due to speculation C_EXPR and X may have the
	 same insns with different speculation types.  And as of
	 now such insns are considered non-equal.

	 However, EXPR_SCHED_TIMES is different -- we must get
	 SCHED_TIMES from a real insn, not a bookkeeping copy.
	 We force this here.  Instead, we may consider merging
	 SCHED_TIMES to the maximum instead of minimum in the
	 below function.  */
      int old_times = EXPR_SCHED_TIMES (lparams->c_expr_merged);

      merge_expr_data (lparams->c_expr_merged, sparams->c_expr, NULL);
      if (EXPR_SCHED_TIMES (sparams->c_expr) == 0)
	EXPR_SCHED_TIMES (lparams->c_expr_merged) = old_times;

      clear_expr (sparams->c_expr);
    }
}

/*  Add used regs for the successor SUCC into SPARAMS->USED_REGS.

   SUCC is one of the SUCCS_NORMAL successors of INSN,
   MOVEOP_DRV_CALL_RES is the result of call code_motion_path_driver on succ or 0,
     if SUCC is one of SUCCS_BACK or SUCCS_OUT.
   STATIC_PARAMS contain USED_REGS set.  */
static void
fur_merge_succs (insn_t insn ATTRIBUTE_UNUSED, insn_t succ,
		 int moveop_drv_call_res,
		 cmpd_local_params_p lparams ATTRIBUTE_UNUSED,
		 void *static_params)
{
  regset succ_live;
  fur_static_params_p sparams = (fur_static_params_p) static_params;

  /* Here we compute live regsets only for branches that do not lie
     on the code motion paths.  These branches correspond to value
     MOVEOP_DRV_CALL_RES==0 and include SUCCS_BACK and SUCCS_OUT, though
     for such branches code_motion_path_driver is not called.  */
  if (moveop_drv_call_res != 0)
    return;

  /* Mark all registers that do not meet the following condition:
     (3) not live on the other path of any conditional branch
     that is passed by the operation, in case original
     operations are not present on both paths of the
     conditional branch.  */
  succ_live = compute_live (succ);
  IOR_REG_SET (sparams->used_regs, succ_live);
}

/* This function is called after the last successor.  Copies LP->C_EXPR_MERGED
   into SP->CEXPR.  */
static void
move_op_after_merge_succs (cmpd_local_params_p lp, void *sparams)
{
  moveop_static_params_p sp = (moveop_static_params_p) sparams;

  sp->c_expr = lp->c_expr_merged;
}

/* Track bookkeeping copies created, insns scheduled, and blocks for
   rescheduling when INSN is found by move_op.  */
static void
track_scheduled_insns_and_blocks (rtx_insn *insn)
{
  /* Even if this insn can be a copy that will be removed during current move_op,
     we still need to count it as an originator.  */
  bitmap_set_bit (current_originators, INSN_UID (insn));

  if (!bitmap_clear_bit (current_copies, INSN_UID (insn)))
    {
      /* Note that original block needs to be rescheduled, as we pulled an
	 instruction out of it.  */
      if (INSN_SCHED_TIMES (insn) > 0)
	bitmap_set_bit (blocks_to_reschedule, BLOCK_FOR_INSN (insn)->index);
      else if (INSN_UID (insn) < first_emitted_uid && !DEBUG_INSN_P (insn))
	num_insns_scheduled++;
    }

  /* For instructions we must immediately remove insn from the
     stream, so subsequent update_data_sets () won't include this
     insn into av_set.
     For expr we must make insn look like "INSN_REG (insn) := c_expr".  */
  if (INSN_UID (insn) > max_uid_before_move_op)
    stat_bookkeeping_copies--;
}

/* Emit a register-register copy for INSN if needed.  Return true if
   emitted one.  PARAMS is the move_op static parameters.  */
static bool
maybe_emit_renaming_copy (rtx_insn *insn,
                          moveop_static_params_p params)
{
  bool insn_emitted  = false;
  rtx cur_reg;

  /* Bail out early when expression can not be renamed at all.  */
  if (!EXPR_SEPARABLE_P (params->c_expr))
    return false;

  cur_reg = expr_dest_reg (params->c_expr);
  gcc_assert (cur_reg && params->dest && REG_P (params->dest));

  /* If original operation has expr and the register chosen for
     that expr is not original operation's dest reg, substitute
     operation's right hand side with the register chosen.  */
  if (REGNO (params->dest) != REGNO (cur_reg))
    {
      insn_t reg_move_insn, reg_move_insn_rtx;

      reg_move_insn_rtx = create_insn_rtx_with_rhs (INSN_VINSN (insn),
                                                    params->dest);
      reg_move_insn = sel_gen_insn_from_rtx_after (reg_move_insn_rtx,
                                                   INSN_EXPR (insn),
                                                   INSN_SEQNO (insn),
                                                   insn);
      EXPR_SPEC_DONE_DS (INSN_EXPR (reg_move_insn)) = 0;
      replace_dest_with_reg_in_expr (params->c_expr, params->dest);

      insn_emitted = true;
      params->was_renamed = true;
    }

  return insn_emitted;
}

/* Emit a speculative check for INSN speculated as EXPR if needed.
   Return true if we've  emitted one.  PARAMS is the move_op static
   parameters.  */
static bool
maybe_emit_speculative_check (rtx_insn *insn, expr_t expr,
                              moveop_static_params_p params)
{
  bool insn_emitted = false;
  insn_t x;
  ds_t check_ds;

  check_ds = get_spec_check_type_for_insn (insn, expr);
  if (check_ds != 0)
    {
      /* A speculation check should be inserted.  */
      x = create_speculation_check (params->c_expr, check_ds, insn);
      insn_emitted = true;
    }
  else
    {
      EXPR_SPEC_DONE_DS (INSN_EXPR (insn)) = 0;
      x = insn;
    }

  gcc_assert (EXPR_SPEC_DONE_DS (INSN_EXPR (x)) == 0
              && EXPR_SPEC_TO_CHECK_DS (INSN_EXPR (x)) == 0);
  return insn_emitted;
}

/* Handle transformations that leave an insn in place of original
   insn such as renaming/speculation.  Return true if one of such
   transformations actually happened, and we have emitted this insn.  */
static bool
handle_emitting_transformations (rtx_insn *insn, expr_t expr,
                                 moveop_static_params_p params)
{
  bool insn_emitted = false;

  insn_emitted = maybe_emit_renaming_copy (insn, params);
  insn_emitted |= maybe_emit_speculative_check (insn, expr, params);

  return insn_emitted;
}

/* If INSN is the only insn in the basic block (not counting JUMP,
   which may be a jump to next insn, and DEBUG_INSNs), we want to
   leave a NOP there till the return to fill_insns.  */

static bool
need_nop_to_preserve_insn_bb (rtx_insn *insn)
{
  insn_t bb_head, bb_end, bb_next, in_next;
  basic_block bb = BLOCK_FOR_INSN (insn);

  bb_head = sel_bb_head (bb);
  bb_end = sel_bb_end (bb);

  if (bb_head == bb_end)
    return true;

  while (bb_head != bb_end && DEBUG_INSN_P (bb_head))
    bb_head = NEXT_INSN (bb_head);

  if (bb_head == bb_end)
    return true;

  while (bb_head != bb_end && DEBUG_INSN_P (bb_end))
    bb_end = PREV_INSN (bb_end);

  if (bb_head == bb_end)
    return true;

  bb_next = NEXT_INSN (bb_head);
  while (bb_next != bb_end && DEBUG_INSN_P (bb_next))
    bb_next = NEXT_INSN (bb_next);

  if (bb_next == bb_end && JUMP_P (bb_end))
    return true;

  in_next = NEXT_INSN (insn);
  while (DEBUG_INSN_P (in_next))
    in_next = NEXT_INSN (in_next);

  if (IN_CURRENT_FENCE_P (in_next))
    return true;

  return false;
}

/* Remove INSN from stream.  When ONLY_DISCONNECT is true, its data
   is not removed but reused when INSN is re-emitted.  */
static void
remove_insn_from_stream (rtx_insn *insn, bool only_disconnect)
{
  /* If there's only one insn in the BB, make sure that a nop is
     inserted into it, so the basic block won't disappear when we'll
     delete INSN below with sel_remove_insn. It should also survive
     till the return to fill_insns.  */
  if (need_nop_to_preserve_insn_bb (insn))
    {
      insn_t nop = get_nop_from_pool (insn);
      gcc_assert (INSN_NOP_P (nop));
      vec_temp_moveop_nops.safe_push (nop);
    }

  sel_remove_insn (insn, only_disconnect, false);
}

/* This function is called when original expr is found.
   INSN - current insn traversed, EXPR - the corresponding expr found.
   LPARAMS is the local parameters of code modion driver, STATIC_PARAMS
   is static parameters of move_op.  */
static void
move_op_orig_expr_found (insn_t insn, expr_t expr,
                         cmpd_local_params_p lparams ATTRIBUTE_UNUSED,
                         void *static_params)
{
  bool only_disconnect;
  moveop_static_params_p params = (moveop_static_params_p) static_params;

  copy_expr_onside (params->c_expr, INSN_EXPR (insn));
  track_scheduled_insns_and_blocks (insn);
  handle_emitting_transformations (insn, expr, params);
  only_disconnect = params->uid == INSN_UID (insn);

  /* Mark that we've disconnected an insn.  */
  if (only_disconnect)
    params->uid = -1;
  remove_insn_from_stream (insn, only_disconnect);
}

/* The function is called when original expr is found.
   INSN - current insn traversed, EXPR - the corresponding expr found,
   crosses_call and original_insns in STATIC_PARAMS are updated.  */
static void
fur_orig_expr_found (insn_t insn, expr_t expr ATTRIBUTE_UNUSED,
                     cmpd_local_params_p lparams ATTRIBUTE_UNUSED,
                     void *static_params)
{
  fur_static_params_p params = (fur_static_params_p) static_params;
  regset tmp;

  if (CALL_P (insn))
    params->crosses_call = true;

  def_list_add (params->original_insns, insn, params->crosses_call);

  /* Mark the registers that do not meet the following condition:
    (2) not among the live registers of the point
	immediately following the first original operation on
	a given downward path, except for the original target
	register of the operation.  */
  tmp = get_clear_regset_from_pool ();
  compute_live_below_insn (insn, tmp);
  AND_COMPL_REG_SET (tmp, INSN_REG_SETS (insn));
  AND_COMPL_REG_SET (tmp, INSN_REG_CLOBBERS (insn));
  IOR_REG_SET (params->used_regs, tmp);
  return_regset_to_pool (tmp);

  /* (*1) We need to add to USED_REGS registers that are read by
     INSN's lhs. This may lead to choosing wrong src register.
     E.g. (scheduling const expr enabled):

	429: ax=0x0	<- Can't use AX for this expr (0x0)
	433: dx=[bp-0x18]
	427: [ax+dx+0x1]=ax
	  REG_DEAD: ax
	168: di=dx
	  REG_DEAD: dx
     */
  /* FIXME: see comment above and enable MEM_P
     in vinsn_separable_p.  */
  gcc_assert (!VINSN_SEPARABLE_P (INSN_VINSN (insn))
	      || !MEM_P (INSN_LHS (insn)));
}

/* This function is called on the ascending pass, before returning from
   current basic block.  */
static void
move_op_at_first_insn (insn_t insn, cmpd_local_params_p lparams,
                       void *static_params)
{
  moveop_static_params_p sparams = (moveop_static_params_p) static_params;
  basic_block book_block = NULL;

  /* When we have removed the boundary insn for scheduling, which also
     happened to be the end insn in its bb, we don't need to update sets.  */
  if (!lparams->removed_last_insn
      && lparams->e1
      && sel_bb_head_p (insn))
    {
      /* We should generate bookkeeping code only if we are not at the
         top level of the move_op.  */
      if (sel_num_cfg_preds_gt_1 (insn))
        book_block = generate_bookkeeping_insn (sparams->c_expr,
                                                lparams->e1, lparams->e2);
      /* Update data sets for the current insn.  */
      update_data_sets (insn);
    }

  /* If bookkeeping code was inserted, we need to update av sets of basic
     block that received bookkeeping.  After generation of bookkeeping insn,
     bookkeeping block does not contain valid av set because we are not following
     the original algorithm in every detail with regards to e.g. renaming
     simple reg-reg copies.  Consider example:

     bookkeeping block           scheduling fence
     \            /
      \    join  /
       ----------
       |        |
       ----------
      /           \
     /             \
     r1 := r2          r1 := r3

     We try to schedule insn "r1 := r3" on the current
     scheduling fence.  Also, note that av set of bookkeeping block
     contain both insns "r1 := r2" and "r1 := r3".  When the insn has
     been scheduled, the CFG is as follows:

     r1 := r3               r1 := r3
     bookkeeping block           scheduling fence
     \            /
      \    join  /
       ----------
       |        |
       ----------
      /          \
     /            \
     r1 := r2

     Here, insn "r1 := r3" was scheduled at the current scheduling point
     and bookkeeping code was generated at the bookeeping block.  This
     way insn "r1 := r2" is no longer available as a whole instruction
     (but only as expr) ahead of insn "r1 := r3" in bookkeeping block.
     This situation is handled by calling update_data_sets.

     Since update_data_sets is called only on the bookkeeping block, and
     it also may have predecessors with av_sets, containing instructions that
     are no longer available, we save all such expressions that become
     unavailable during data sets update on the bookkeeping block in
     VEC_BOOKKEEPING_BLOCKED_VINSNS.  Later we avoid selecting such
     expressions for scheduling.  This allows us to avoid recomputation of
     av_sets outside the code motion path.  */

  if (book_block)
    update_and_record_unavailable_insns (book_block);

  /* If INSN was previously marked for deletion, it's time to do it.  */
  if (lparams->removed_last_insn)
    insn = PREV_INSN (insn);

  /* Do not tidy control flow at the topmost moveop, as we can erroneously
     kill a block with a single nop in which the insn should be emitted.  */
  if (lparams->e1)
    tidy_control_flow (BLOCK_FOR_INSN (insn), true);
}

/* This function is called on the ascending pass, before returning from the
   current basic block.  */
static void
fur_at_first_insn (insn_t insn,
                   cmpd_local_params_p lparams ATTRIBUTE_UNUSED,
                   void *static_params ATTRIBUTE_UNUSED)
{
  gcc_assert (!sel_bb_head_p (insn) || AV_SET_VALID_P (insn)
	      || AV_LEVEL (insn) == -1);
}

/* Called on the backward stage of recursion to call moveup_expr for insn
   and sparams->c_expr.  */
static void
move_op_ascend (insn_t insn, void *static_params)
{
  enum MOVEUP_EXPR_CODE res;
  moveop_static_params_p sparams = (moveop_static_params_p) static_params;

  if (! INSN_NOP_P (insn))
    {
      res = moveup_expr_cached (sparams->c_expr, insn, false);
      gcc_assert (res != MOVEUP_EXPR_NULL);
    }

  /* Update liveness for this insn as it was invalidated.  */
  update_liveness_on_insn (insn);
}

/* This function is called on enter to the basic block.
   Returns TRUE if this block already have been visited and
   code_motion_path_driver should return 1, FALSE otherwise.  */
static int
fur_on_enter (insn_t insn ATTRIBUTE_UNUSED, cmpd_local_params_p local_params,
	      void *static_params, bool visited_p)
{
  fur_static_params_p sparams = (fur_static_params_p) static_params;

  if (visited_p)
    {
      /* If we have found something below this block, there should be at
	 least one insn in ORIGINAL_INSNS.  */
      gcc_assert (*sparams->original_insns);

      /* Adjust CROSSES_CALL, since we may have come to this block along
	 different path.  */
      DEF_LIST_DEF (*sparams->original_insns)->crosses_call
	  |= sparams->crosses_call;
    }
  else
    local_params->old_original_insns = *sparams->original_insns;

  return 1;
}

/* Same as above but for move_op.   */
static int
move_op_on_enter (insn_t insn ATTRIBUTE_UNUSED,
                  cmpd_local_params_p local_params ATTRIBUTE_UNUSED,
                  void *static_params ATTRIBUTE_UNUSED, bool visited_p)
{
  if (visited_p)
    return -1;
  return 1;
}

/* This function is called while descending current basic block if current
   insn is not the original EXPR we're searching for.

   Return value: FALSE, if code_motion_path_driver should perform a local
			cleanup and return 0 itself;
		 TRUE, if code_motion_path_driver should continue.  */
static bool
move_op_orig_expr_not_found (insn_t insn, av_set_t orig_ops ATTRIBUTE_UNUSED,
			    void *static_params)
{
  moveop_static_params_p sparams = (moveop_static_params_p) static_params;

  sparams->failed_insn = insn;

  /* If we're scheduling separate expr, in order to generate correct code
     we need to stop the search at bookkeeping code generated with the
     same destination register or memory.  */
  if (lhs_of_insn_equals_to_dest_p (insn, sparams->dest))
    return false;
  return true;
}

/* This function is called while descending current basic block if current
   insn is not the original EXPR we're searching for.

   Return value: TRUE (code_motion_path_driver should continue).  */
static bool
fur_orig_expr_not_found (insn_t insn, av_set_t orig_ops, void *static_params)
{
  bool mutexed;
  expr_t r;
  av_set_iterator avi;
  fur_static_params_p sparams = (fur_static_params_p) static_params;

  if (CALL_P (insn))
    sparams->crosses_call = true;
  else if (DEBUG_INSN_P (insn))
    return true;

  /* If current insn we are looking at cannot be executed together
     with original insn, then we can skip it safely.

     Example: ORIG_OPS = { (p6) r14 = sign_extend (r15); }
	      INSN = (!p6) r14 = r14 + 1;

     Here we can schedule ORIG_OP with lhs = r14, though only
     looking at the set of used and set registers of INSN we must
     forbid it.  So, add set/used in INSN registers to the
     untouchable set only if there is an insn in ORIG_OPS that can
     affect INSN.  */
  mutexed = true;
  FOR_EACH_EXPR (r, avi, orig_ops)
    if (!sched_insns_conditions_mutex_p (insn, EXPR_INSN_RTX (r)))
      {
	mutexed = false;
	break;
      }

  /* Mark all registers that do not meet the following condition:
     (1) Not set or read on any path from xi to an instance of the
	 original operation.  */
  if (!mutexed)
    {
      IOR_REG_SET (sparams->used_regs, INSN_REG_SETS (insn));
      IOR_REG_SET (sparams->used_regs, INSN_REG_USES (insn));
      IOR_REG_SET (sparams->used_regs, INSN_REG_CLOBBERS (insn));
    }

  return true;
}

/* Hooks and data to perform move_op operations with code_motion_path_driver.  */
struct code_motion_path_driver_info_def move_op_hooks = {
  move_op_on_enter,
  move_op_orig_expr_found,
  move_op_orig_expr_not_found,
  move_op_merge_succs,
  move_op_after_merge_succs,
  move_op_ascend,
  move_op_at_first_insn,
  SUCCS_NORMAL,
  "move_op"
};

/* Hooks and data to perform find_used_regs operations
   with code_motion_path_driver.  */
struct code_motion_path_driver_info_def fur_hooks = {
  fur_on_enter,
  fur_orig_expr_found,
  fur_orig_expr_not_found,
  fur_merge_succs,
  NULL, /* fur_after_merge_succs */
  NULL, /* fur_ascend */
  fur_at_first_insn,
  SUCCS_ALL,
  "find_used_regs"
};

/* Traverse all successors of INSN.  For each successor that is SUCCS_NORMAL
   code_motion_path_driver is called recursively.  Original operation
   was found at least on one path that is starting with one of INSN's
   successors (this fact is asserted).  ORIG_OPS is expressions we're looking
   for, PATH is the path we've traversed, STATIC_PARAMS is the parameters
   of either move_op or find_used_regs depending on the caller.

   Return 0 if we haven't found expression, 1 if we found it, -1 if we don't
   know for sure at this point.  */
static int
code_motion_process_successors (insn_t insn, av_set_t orig_ops,
                                ilist_t path, void *static_params)
{
  int res = 0;
  succ_iterator succ_i;
  insn_t succ;
  basic_block bb;
  int old_index;
  unsigned old_succs;

  struct cmpd_local_params lparams;
  expr_def _x;

  lparams.c_expr_local = &_x;
  lparams.c_expr_merged = NULL;

  /* We need to process only NORMAL succs for move_op, and collect live
     registers from ALL branches (including those leading out of the
     region) for find_used_regs.

     In move_op, there can be a case when insn's bb number has changed
     due to created bookkeeping.  This happens very rare, as we need to
     move expression from the beginning to the end of the same block.
     Rescan successors in this case.  */

 rescan:
  bb = BLOCK_FOR_INSN (insn);
  old_index = bb->index;
  old_succs = EDGE_COUNT (bb->succs);

  FOR_EACH_SUCC_1 (succ, succ_i, insn, code_motion_path_driver_info->succ_flags)
    {
      int b;

      lparams.e1 = succ_i.e1;
      lparams.e2 = succ_i.e2;

      /* Go deep into recursion only for NORMAL edges (non-backedges within the
	 current region).  */
      if (succ_i.current_flags == SUCCS_NORMAL)
	b = code_motion_path_driver (succ, orig_ops, path, &lparams,
				     static_params);
      else
	b = 0;

      /* Merge c_expres found or unify live register sets from different
	 successors.  */
      code_motion_path_driver_info->merge_succs (insn, succ, b, &lparams,
						 static_params);
      if (b == 1)
        res = b;
      else if (b == -1 && res != 1)
        res = b;

      /* We have simplified the control flow below this point.  In this case,
         the iterator becomes invalid.  We need to try again.
	 If we have removed the insn itself, it could be only an
	 unconditional jump.  Thus, do not rescan but break immediately --
	 we have already visited the only successor block.  */
      if (!BLOCK_FOR_INSN (insn))
	{
	  if (sched_verbose >= 6)
	    sel_print ("Not doing rescan: already visited the only successor"
		       " of block %d\n", old_index);
	  break;
	}
      if (BLOCK_FOR_INSN (insn)->index != old_index
          || EDGE_COUNT (bb->succs) != old_succs)
        {
	  if (sched_verbose >= 6)
	    sel_print ("Rescan: CFG was simplified below insn %d, block %d\n",
		       INSN_UID (insn), BLOCK_FOR_INSN (insn)->index);
          insn = sel_bb_end (BLOCK_FOR_INSN (insn));
          goto rescan;
        }
    }

  /* Here, RES==1 if original expr was found at least for one of the
     successors.  After the loop, RES may happen to have zero value
     only if at some point the expr searched is present in av_set, but is
     not found below.  In most cases, this situation is an error.
     The exception is when the original operation is blocked by
     bookkeeping generated for another fence or for another path in current
     move_op.  */
  gcc_checking_assert (res == 1
		       || (res == 0
			    && av_set_could_be_blocked_by_bookkeeping_p (orig_ops, static_params))
		       || res == -1);

  /* Merge data, clean up, etc.  */
  if (res != -1 && code_motion_path_driver_info->after_merge_succs)
    code_motion_path_driver_info->after_merge_succs (&lparams, static_params);

  return res;
}


/* Perform a cleanup when the driver is about to terminate.  ORIG_OPS_P
   is the pointer to the av set with expressions we were looking for,
   PATH_P is the pointer to the traversed path.  */
static inline void
code_motion_path_driver_cleanup (av_set_t *orig_ops_p, ilist_t *path_p)
{
  ilist_remove (path_p);
  av_set_clear (orig_ops_p);
}

/* The driver function that implements move_op or find_used_regs
   functionality dependent whether code_motion_path_driver_INFO is set to
   &MOVE_OP_HOOKS or &FUR_HOOKS.  This function implements the common parts
   of code (CFG traversal etc) that are shared among both functions.  INSN
   is the insn we're starting the search from, ORIG_OPS are the expressions
   we're searching for, PATH is traversed path, LOCAL_PARAMS_IN are local
   parameters of the driver, and STATIC_PARAMS are static parameters of
   the caller.

   Returns whether original instructions were found.  Note that top-level
   code_motion_path_driver always returns true.  */
static int
code_motion_path_driver (insn_t insn, av_set_t orig_ops, ilist_t path,
			 cmpd_local_params_p local_params_in,
			 void *static_params)
{
  expr_t expr = NULL;
  basic_block bb = BLOCK_FOR_INSN (insn);
  insn_t first_insn, bb_tail, before_first;
  bool removed_last_insn = false;

  if (sched_verbose >= 6)
    {
      sel_print ("%s (", code_motion_path_driver_info->routine_name);
      dump_insn (insn);
      sel_print (",");
      dump_av_set (orig_ops);
      sel_print (")\n");
    }

  gcc_assert (orig_ops);

  /* If no original operations exist below this insn, return immediately.  */
  if (is_ineligible_successor (insn, path))
    {
      if (sched_verbose >= 6)
        sel_print ("Insn %d is ineligible successor\n", INSN_UID (insn));
      return false;
    }

  /* The block can have invalid av set, in which case it was created earlier
     during move_op.  Return immediately.  */
  if (sel_bb_head_p (insn))
    {
      if (! AV_SET_VALID_P (insn))
        {
          if (sched_verbose >= 6)
            sel_print ("Returned from block %d as it had invalid av set\n",
                       bb->index);
          return false;
        }

      if (bitmap_bit_p (code_motion_visited_blocks, bb->index))
        {
          /* We have already found an original operation on this branch, do not
             go any further and just return TRUE here.  If we don't stop here,
             function can have exponential behavior even on the small code
             with many different paths (e.g. with data speculation and
             recovery blocks).  */
          if (sched_verbose >= 6)
            sel_print ("Block %d already visited in this traversal\n", bb->index);
          if (code_motion_path_driver_info->on_enter)
            return code_motion_path_driver_info->on_enter (insn,
                                                           local_params_in,
                                                           static_params,
                                                           true);
        }
    }

  if (code_motion_path_driver_info->on_enter)
    code_motion_path_driver_info->on_enter (insn, local_params_in,
                                            static_params, false);
  orig_ops = av_set_copy (orig_ops);

  /* Filter the orig_ops set.  */
  if (AV_SET_VALID_P (insn))
    av_set_code_motion_filter (&orig_ops, AV_SET (insn));

  /* If no more original ops, return immediately.  */
  if (!orig_ops)
    {
      if (sched_verbose >= 6)
        sel_print ("No intersection with av set of block %d\n", bb->index);
      return false;
    }

  /* For non-speculative insns we have to leave only one form of the
     original operation, because if we don't, we may end up with
     different C_EXPRes and, consequently, with bookkeepings for different
     expression forms along the same code motion path.  That may lead to
     generation of incorrect code.  So for each code motion we stick to
     the single form of the instruction,  except for speculative insns
     which we need to keep in different forms with all speculation
     types.  */
  av_set_leave_one_nonspec (&orig_ops);

  /* It is not possible that all ORIG_OPS are filtered out.  */
  gcc_assert (orig_ops);

  /* It is enough to place only heads and tails of visited basic blocks into
     the PATH.  */
  ilist_add (&path, insn);
  first_insn = insn;
  bb_tail = sel_bb_end (bb);

  /* Descend the basic block in search of the original expr; this part
     corresponds to the part of the original move_op procedure executed
     before the recursive call.  */
  for (;;)
    {
      /* Look at the insn and decide if it could be an ancestor of currently
	 scheduling operation.  If it is so, then the insn "dest = op" could
	 either be replaced with "dest = reg", because REG now holds the result
	 of OP, or just removed, if we've scheduled the insn as a whole.

	 If this insn doesn't contain currently scheduling OP, then proceed
	 with searching and look at its successors.  Operations we're searching
	 for could have changed when moving up through this insn via
	 substituting.  In this case, perform unsubstitution on them first.

	 When traversing the DAG below this insn is finished, insert
	 bookkeeping code, if the insn is a joint point, and remove
	 leftovers.  */

      expr = av_set_lookup (orig_ops, INSN_VINSN (insn));
      if (expr)
	{
	  insn_t last_insn = PREV_INSN (insn);

	  /* We have found the original operation.   */
          if (sched_verbose >= 6)
            sel_print ("Found original operation at insn %d\n", INSN_UID (insn));

	  code_motion_path_driver_info->orig_expr_found
            (insn, expr, local_params_in, static_params);

	  /* Step back, so on the way back we'll start traversing from the
	     previous insn (or we'll see that it's bb_note and skip that
	     loop).  */
          if (insn == first_insn)
            {
              first_insn = NEXT_INSN (last_insn);
              removed_last_insn = sel_bb_end_p (last_insn);
            }
	  insn = last_insn;
	  break;
	}
      else
	{
	  /* We haven't found the original expr, continue descending the basic
	     block.  */
	  if (code_motion_path_driver_info->orig_expr_not_found
              (insn, orig_ops, static_params))
	    {
	      /* Av set ops could have been changed when moving through this
	         insn.  To find them below it, we have to un-substitute them.  */
	      undo_transformations (&orig_ops, insn);
	    }
	  else
	    {
	      /* Clean up and return, if the hook tells us to do so.  It may
		 happen if we've encountered the previously created
		 bookkeeping.  */
	      code_motion_path_driver_cleanup (&orig_ops, &path);
	      return -1;
	    }

	  gcc_assert (orig_ops);
        }

      /* Stop at insn if we got to the end of BB.  */
      if (insn == bb_tail)
	break;

      insn = NEXT_INSN (insn);
    }

  /* Here INSN either points to the insn before the original insn (may be
     bb_note, if original insn was a bb_head) or to the bb_end.  */
  if (!expr)
    {
      int res;
      rtx_insn *last_insn = PREV_INSN (insn);
      bool added_to_path;

      gcc_assert (insn == sel_bb_end (bb));

      /* Add bb tail to PATH (but it doesn't make any sense if it's a bb_head -
	 it's already in PATH then).  */
      if (insn != first_insn)
	{
	  ilist_add (&path, insn);
	  added_to_path = true;
	}
      else
        added_to_path = false;

      /* Process_successors should be able to find at least one
	 successor for which code_motion_path_driver returns TRUE.  */
      res = code_motion_process_successors (insn, orig_ops,
                                            path, static_params);

      /* Jump in the end of basic block could have been removed or replaced
         during code_motion_process_successors, so recompute insn as the
         last insn in bb.  */
      if (NEXT_INSN (last_insn) != insn)
        {
          insn = sel_bb_end (bb);
          first_insn = sel_bb_head (bb);
        }

      /* Remove bb tail from path.  */
      if (added_to_path)
	ilist_remove (&path);

      if (res != 1)
	{
	  /* This is the case when one of the original expr is no longer available
	     due to bookkeeping created on this branch with the same register.
	     In the original algorithm, which doesn't have update_data_sets call
	     on a bookkeeping block, it would simply result in returning
	     FALSE when we've encountered a previously generated bookkeeping
	     insn in moveop_orig_expr_not_found.  */
	  code_motion_path_driver_cleanup (&orig_ops, &path);
	  return res;
	}
    }

  /* Don't need it any more.  */
  av_set_clear (&orig_ops);

  /* Backward pass: now, when we have C_EXPR computed, we'll drag it to
     the beginning of the basic block.  */
  before_first = PREV_INSN (first_insn);
  while (insn != before_first)
    {
      if (code_motion_path_driver_info->ascend)
	code_motion_path_driver_info->ascend (insn, static_params);

      insn = PREV_INSN (insn);
    }

  /* Now we're at the bb head.  */
  insn = first_insn;
  ilist_remove (&path);
  local_params_in->removed_last_insn = removed_last_insn;
  code_motion_path_driver_info->at_first_insn (insn, local_params_in, static_params);

  /* This should be the very last operation as at bb head we could change
     the numbering by creating bookkeeping blocks.  */
  if (removed_last_insn)
    insn = PREV_INSN (insn);

  /* If we have simplified the control flow and removed the first jump insn,
     there's no point in marking this block in the visited blocks bitmap.  */
  if (BLOCK_FOR_INSN (insn))
    bitmap_set_bit (code_motion_visited_blocks, BLOCK_FOR_INSN (insn)->index);
  return true;
}

/* Move up the operations from ORIG_OPS set traversing the dag starting
   from INSN.  PATH represents the edges traversed so far.
   DEST is the register chosen for scheduling the current expr.  Insert
   bookkeeping code in the join points.  EXPR_VLIW is the chosen expression,
   C_EXPR is how it looks like at the given cfg point.
   Set *SHOULD_MOVE to indicate whether we have only disconnected
   one of the insns found.

   Returns whether original instructions were found, which is asserted
   to be true in the caller.  */
static bool
move_op (insn_t insn, av_set_t orig_ops, expr_t expr_vliw,
         rtx dest, expr_t c_expr, bool *should_move)
{
  struct moveop_static_params sparams;
  struct cmpd_local_params lparams;
  int res;

  /* Init params for code_motion_path_driver.  */
  sparams.dest = dest;
  sparams.c_expr = c_expr;
  sparams.uid = INSN_UID (EXPR_INSN_RTX (expr_vliw));
  sparams.failed_insn = NULL;
  sparams.was_renamed = false;
  lparams.e1 = NULL;

  /* We haven't visited any blocks yet.  */
  bitmap_clear (code_motion_visited_blocks);

  /* Set appropriate hooks and data.  */
  code_motion_path_driver_info = &move_op_hooks;
  res = code_motion_path_driver (insn, orig_ops, NULL, &lparams, &sparams);

  gcc_assert (res != -1);

  if (sparams.was_renamed)
    EXPR_WAS_RENAMED (expr_vliw) = true;

  *should_move = (sparams.uid == -1);

  return res;
}


/* Functions that work with regions.  */

/* Current number of seqno used in init_seqno and init_seqno_1.  */
static int cur_seqno;

/* A helper for init_seqno.  Traverse the region starting from BB and
   compute seqnos for visited insns, marking visited bbs in VISITED_BBS.
   Clear visited blocks from BLOCKS_TO_RESCHEDULE.  */
static void
init_seqno_1 (basic_block bb, sbitmap visited_bbs, bitmap blocks_to_reschedule)
{
  int bbi = BLOCK_TO_BB (bb->index);
  insn_t insn;
  insn_t succ_insn;
  succ_iterator si;

  rtx_note *note = bb_note (bb);
  bitmap_set_bit (visited_bbs, bbi);
  if (blocks_to_reschedule)
    bitmap_clear_bit (blocks_to_reschedule, bb->index);

  FOR_EACH_SUCC_1 (succ_insn, si, BB_END (bb),
		   SUCCS_NORMAL | SUCCS_SKIP_TO_LOOP_EXITS)
    {
      basic_block succ = BLOCK_FOR_INSN (succ_insn);
      int succ_bbi = BLOCK_TO_BB (succ->index);

      gcc_assert (in_current_region_p (succ));

      if (!bitmap_bit_p (visited_bbs, succ_bbi))
	{
	  gcc_assert (succ_bbi > bbi);

	  init_seqno_1 (succ, visited_bbs, blocks_to_reschedule);
	}
      else if (blocks_to_reschedule)
        bitmap_set_bit (forced_ebb_heads, succ->index);
    }

  for (insn = BB_END (bb); insn != note; insn = PREV_INSN (insn))
    INSN_SEQNO (insn) = cur_seqno--;
}

/* Initialize seqnos for the current region.  BLOCKS_TO_RESCHEDULE contains
   blocks on which we're rescheduling when pipelining, FROM is the block where
   traversing region begins (it may not be the head of the region when
   pipelining, but the head of the loop instead).

   Returns the maximal seqno found.  */
static int
init_seqno (bitmap blocks_to_reschedule, basic_block from)
{
  bitmap_iterator bi;
  unsigned bbi;

  auto_sbitmap visited_bbs (current_nr_blocks);

  if (blocks_to_reschedule)
    {
      bitmap_ones (visited_bbs);
      EXECUTE_IF_SET_IN_BITMAP (blocks_to_reschedule, 0, bbi, bi)
        {
	  gcc_assert (BLOCK_TO_BB (bbi) < current_nr_blocks);
          bitmap_clear_bit (visited_bbs, BLOCK_TO_BB (bbi));
	}
    }
  else
    {
      bitmap_clear (visited_bbs);
      from = EBB_FIRST_BB (0);
    }

  cur_seqno = sched_max_luid - 1;
  init_seqno_1 (from, visited_bbs, blocks_to_reschedule);

  /* cur_seqno may be positive if the number of instructions is less than
     sched_max_luid - 1 (when rescheduling or if some instructions have been
     removed by the call to purge_empty_blocks in sel_sched_region_1).  */
  gcc_assert (cur_seqno >= 0);

  return sched_max_luid - 1;
}

/* Initialize scheduling parameters for current region.  */
static void
sel_setup_region_sched_flags (void)
{
  enable_schedule_as_rhs_p = 1;
  bookkeeping_p = 1;
  pipelining_p = (bookkeeping_p
                  && (flag_sel_sched_pipelining != 0)
		  && current_loop_nest != NULL
		  && loop_has_exit_edges (current_loop_nest));
  max_insns_to_rename = PARAM_VALUE (PARAM_SELSCHED_INSNS_TO_RENAME);
  max_ws = MAX_WS;
}

/* Return true if all basic blocks of current region are empty.  */
static bool
current_region_empty_p (void)
{
  int i;
  for (i = 0; i < current_nr_blocks; i++)
    if (! sel_bb_empty_p (BASIC_BLOCK_FOR_FN (cfun, BB_TO_BLOCK (i))))
      return false;

  return true;
}

/* Prepare and verify loop nest for pipelining.  */
static void
setup_current_loop_nest (int rgn, bb_vec_t *bbs)
{
  current_loop_nest = get_loop_nest_for_rgn (rgn);

  if (!current_loop_nest)
    return;

  /* If this loop has any saved loop preheaders from nested loops,
     add these basic blocks to the current region.  */
  sel_add_loop_preheaders (bbs);

  /* Check that we're starting with a valid information.  */
  gcc_assert (loop_latch_edge (current_loop_nest));
  gcc_assert (LOOP_MARKED_FOR_PIPELINING_P (current_loop_nest));
}

/* Compute instruction priorities for current region.  */
static void
sel_compute_priorities (int rgn)
{
  sched_rgn_compute_dependencies (rgn);

  /* Compute insn priorities in haifa style.  Then free haifa style
     dependencies that we've calculated for this.  */
  compute_priorities ();

  if (sched_verbose >= 5)
    debug_rgn_dependencies (0);

  free_rgn_deps ();
}

/* Init scheduling data for RGN.  Returns true when this region should not
   be scheduled.  */
static bool
sel_region_init (int rgn)
{
  int i;
  bb_vec_t bbs;

  rgn_setup_region (rgn);

  /* Even if sched_is_disabled_for_current_region_p() is true, we still
     do region initialization here so the region can be bundled correctly,
     but we'll skip the scheduling in sel_sched_region ().  */
  if (current_region_empty_p ())
    return true;

  bbs.create (current_nr_blocks);

  for (i = 0; i < current_nr_blocks; i++)
    bbs.quick_push (BASIC_BLOCK_FOR_FN (cfun, BB_TO_BLOCK (i)));

  sel_init_bbs (bbs);

  if (flag_sel_sched_pipelining)
    setup_current_loop_nest (rgn, &bbs);

  sel_setup_region_sched_flags ();

  /* Initialize luids and dependence analysis which both sel-sched and haifa
     need.  */
  sched_init_luids (bbs);
  sched_deps_init (false);

  /* Initialize haifa data.  */
  rgn_setup_sched_infos ();
  sel_set_sched_flags ();
  haifa_init_h_i_d (bbs);

  sel_compute_priorities (rgn);
  init_deps_global ();

  /* Main initialization.  */
  sel_setup_sched_infos ();
  sel_init_global_and_expr (bbs);

  bbs.release ();

  blocks_to_reschedule = BITMAP_ALLOC (NULL);

  /* Init correct liveness sets on each instruction of a single-block loop.
     This is the only situation when we can't update liveness when calling
     compute_live for the first insn of the loop.  */
  if (current_loop_nest)
    {
      int header =
	(sel_is_loop_preheader_p (BASIC_BLOCK_FOR_FN (cfun, BB_TO_BLOCK (0)))
	 ? 1
	 : 0);

      if (current_nr_blocks == header + 1)
        update_liveness_on_insn
          (sel_bb_head (BASIC_BLOCK_FOR_FN (cfun, BB_TO_BLOCK (header))));
    }

  /* Set hooks so that no newly generated insn will go out unnoticed.  */
  sel_register_cfg_hooks ();

  /* !!! We call target.sched.init () for the whole region, but we invoke
     targetm.sched.finish () for every ebb.  */
  if (targetm.sched.init)
    /* None of the arguments are actually used in any target.  */
    targetm.sched.init (sched_dump, sched_verbose, -1);

  first_emitted_uid = get_max_uid () + 1;
  preheader_removed = false;

  /* Reset register allocation ticks array.  */
  memset (reg_rename_tick, 0, sizeof reg_rename_tick);
  reg_rename_this_tick = 0;

  bitmap_initialize (forced_ebb_heads, 0);
  bitmap_clear (forced_ebb_heads);

  setup_nop_vinsn ();
  current_copies = BITMAP_ALLOC (NULL);
  current_originators = BITMAP_ALLOC (NULL);
  code_motion_visited_blocks = BITMAP_ALLOC (NULL);

  return false;
}

/* Simplify insns after the scheduling.  */
static void
simplify_changed_insns (void)
{
  int i;

  for (i = 0; i < current_nr_blocks; i++)
    {
      basic_block bb = BASIC_BLOCK_FOR_FN (cfun, BB_TO_BLOCK (i));
      rtx_insn *insn;

      FOR_BB_INSNS (bb, insn)
	if (INSN_P (insn))
	  {
	    expr_t expr = INSN_EXPR (insn);

	    if (EXPR_WAS_SUBSTITUTED (expr))
	      validate_simplify_insn (insn);
	  }
    }
}

/* Find boundaries of the EBB starting from basic block BB, marking blocks of
   this EBB in SCHEDULED_BLOCKS and appropriately filling in HEAD, TAIL,
   PREV_HEAD, and NEXT_TAIL fields of CURRENT_SCHED_INFO structure.  */
static void
find_ebb_boundaries (basic_block bb, bitmap scheduled_blocks)
{
  rtx_insn *head, *tail;
  basic_block bb1 = bb;
  if (sched_verbose >= 2)
    sel_print ("Finishing schedule in bbs: ");

  do
    {
      bitmap_set_bit (scheduled_blocks, BLOCK_TO_BB (bb1->index));

      if (sched_verbose >= 2)
	sel_print ("%d; ", bb1->index);
    }
  while (!bb_ends_ebb_p (bb1) && (bb1 = bb_next_bb (bb1)));

  if (sched_verbose >= 2)
    sel_print ("\n");

  get_ebb_head_tail (bb, bb1, &head, &tail);

  current_sched_info->head = head;
  current_sched_info->tail = tail;
  current_sched_info->prev_head = PREV_INSN (head);
  current_sched_info->next_tail = NEXT_INSN (tail);
}

/* Regenerate INSN_SCHED_CYCLEs for insns of current EBB.  */
static void
reset_sched_cycles_in_current_ebb (void)
{
  int last_clock = 0;
  int haifa_last_clock = -1;
  int haifa_clock = 0;
  int issued_insns = 0;
  insn_t insn;

  if (targetm.sched.init)
    {
      /* None of the arguments are actually used in any target.
	 NB: We should have md_reset () hook for cases like this.  */
      targetm.sched.init (sched_dump, sched_verbose, -1);
    }

  state_reset (curr_state);
  advance_state (curr_state);

  for (insn = current_sched_info->head;
       insn != current_sched_info->next_tail;
       insn = NEXT_INSN (insn))
    {
      int cost, haifa_cost;
      int sort_p;
      bool asm_p, real_insn, after_stall, all_issued;
      int clock;

      if (!INSN_P (insn))
	continue;

      asm_p = false;
      real_insn = recog_memoized (insn) >= 0;
      clock = INSN_SCHED_CYCLE (insn);

      cost = clock - last_clock;

      /* Initialize HAIFA_COST.  */
      if (! real_insn)
	{
	  asm_p = INSN_ASM_P (insn);

	  if (asm_p)
	    /* This is asm insn which *had* to be scheduled first
	       on the cycle.  */
	    haifa_cost = 1;
	  else
	    /* This is a use/clobber insn.  It should not change
	       cost.  */
	    haifa_cost = 0;
	}
      else
        haifa_cost = estimate_insn_cost (insn, curr_state);

      /* Stall for whatever cycles we've stalled before.  */
      after_stall = 0;
      if (INSN_AFTER_STALL_P (insn) && cost > haifa_cost)
        {
          haifa_cost = cost;
          after_stall = 1;
        }
      all_issued = issued_insns == issue_rate;
      if (haifa_cost == 0 && all_issued)
	haifa_cost = 1;
      if (haifa_cost > 0)
	{
	  int i = 0;

	  while (haifa_cost--)
	    {
	      advance_state (curr_state);
	      issued_insns = 0;
              i++;

	      if (sched_verbose >= 2)
                {
                  sel_print ("advance_state (state_transition)\n");
                  debug_state (curr_state);
                }

              /* The DFA may report that e.g. insn requires 2 cycles to be
                 issued, but on the next cycle it says that insn is ready
                 to go.  Check this here.  */
              if (!after_stall
                  && real_insn
                  && haifa_cost > 0
                  && estimate_insn_cost (insn, curr_state) == 0)
                break;

              /* When the data dependency stall is longer than the DFA stall,
                 and when we have issued exactly issue_rate insns and stalled,
                 it could be that after this longer stall the insn will again
                 become unavailable  to the DFA restrictions.  Looks strange
                 but happens e.g. on x86-64.  So recheck DFA on the last
                 iteration.  */
              if ((after_stall || all_issued)
                  && real_insn
                  && haifa_cost == 0)
                haifa_cost = estimate_insn_cost (insn, curr_state);
            }

	  haifa_clock += i;
          if (sched_verbose >= 2)
            sel_print ("haifa clock: %d\n", haifa_clock);
	}
      else
	gcc_assert (haifa_cost == 0);

      if (sched_verbose >= 2)
	sel_print ("Haifa cost for insn %d: %d\n", INSN_UID (insn), haifa_cost);

      if (targetm.sched.dfa_new_cycle)
	while (targetm.sched.dfa_new_cycle (sched_dump, sched_verbose, insn,
					    haifa_last_clock, haifa_clock,
					    &sort_p))
	  {
	    advance_state (curr_state);
	    issued_insns = 0;
	    haifa_clock++;
	    if (sched_verbose >= 2)
              {
                sel_print ("advance_state (dfa_new_cycle)\n");
                debug_state (curr_state);
		sel_print ("haifa clock: %d\n", haifa_clock + 1);
              }
          }

      if (real_insn)
	{
	  static state_t temp = NULL;

	  if (!temp)
	    temp = xmalloc (dfa_state_size);
	  memcpy (temp, curr_state, dfa_state_size);

	  cost = state_transition (curr_state, insn);
	  if (memcmp (temp, curr_state, dfa_state_size))
	    issued_insns++;

          if (sched_verbose >= 2)
	    {
	      sel_print ("scheduled insn %d, clock %d\n", INSN_UID (insn),
			 haifa_clock + 1);
              debug_state (curr_state);
	    }
	  gcc_assert (cost < 0);
	}

      if (targetm.sched.variable_issue)
	targetm.sched.variable_issue (sched_dump, sched_verbose, insn, 0);

      INSN_SCHED_CYCLE (insn) = haifa_clock;

      last_clock = clock;
      haifa_last_clock = haifa_clock;
    }
}

/* Put TImode markers on insns starting a new issue group.  */
static void
put_TImodes (void)
{
  int last_clock = -1;
  insn_t insn;

  for (insn = current_sched_info->head; insn != current_sched_info->next_tail;
       insn = NEXT_INSN (insn))
    {
      int cost, clock;

      if (!INSN_P (insn))
	continue;

      clock = INSN_SCHED_CYCLE (insn);
      cost = (last_clock == -1) ? 1 : clock - last_clock;

      gcc_assert (cost >= 0);

      if (issue_rate > 1
	  && GET_CODE (PATTERN (insn)) != USE
	  && GET_CODE (PATTERN (insn)) != CLOBBER)
	{
	  if (reload_completed && cost > 0)
	    PUT_MODE (insn, TImode);

	  last_clock = clock;
	}

      if (sched_verbose >= 2)
	sel_print ("Cost for insn %d is %d\n", INSN_UID (insn), cost);
    }
}

/* Perform MD_FINISH on EBBs comprising current region.  When
   RESET_SCHED_CYCLES_P is true, run a pass emulating the scheduler
   to produce correct sched cycles on insns.  */
static void
sel_region_target_finish (bool reset_sched_cycles_p)
{
  int i;
  bitmap scheduled_blocks = BITMAP_ALLOC (NULL);

  for (i = 0; i < current_nr_blocks; i++)
    {
      if (bitmap_bit_p (scheduled_blocks, i))
	continue;

      /* While pipelining outer loops, skip bundling for loop
	 preheaders.  Those will be rescheduled in the outer loop.  */
      if (sel_is_loop_preheader_p (EBB_FIRST_BB (i)))
	continue;

      find_ebb_boundaries (EBB_FIRST_BB (i), scheduled_blocks);

      if (no_real_insns_p (current_sched_info->head, current_sched_info->tail))
	continue;

      if (reset_sched_cycles_p)
	reset_sched_cycles_in_current_ebb ();

      if (targetm.sched.init)
	targetm.sched.init (sched_dump, sched_verbose, -1);

      put_TImodes ();

      if (targetm.sched.finish)
	{
	  targetm.sched.finish (sched_dump, sched_verbose);

	  /* Extend luids so that insns generated by the target will
	     get zero luid.  */
	  sched_extend_luids ();
	}
    }

  BITMAP_FREE (scheduled_blocks);
}

/* Free the scheduling data for the current region.  When RESET_SCHED_CYCLES_P
   is true, make an additional pass emulating scheduler to get correct insn
   cycles for md_finish calls.  */
static void
sel_region_finish (bool reset_sched_cycles_p)
{
  simplify_changed_insns ();
  sched_finish_ready_list ();
  free_nop_pool ();

  /* Free the vectors.  */
  vec_av_set.release ();
  BITMAP_FREE (current_copies);
  BITMAP_FREE (current_originators);
  BITMAP_FREE (code_motion_visited_blocks);
  vinsn_vec_free (vec_bookkeeping_blocked_vinsns);
  vinsn_vec_free (vec_target_unavailable_vinsns);

  /* If LV_SET of the region head should be updated, do it now because
     there will be no other chance.  */
  {
    succ_iterator si;
    insn_t insn;

    FOR_EACH_SUCC_1 (insn, si, bb_note (EBB_FIRST_BB (0)),
                     SUCCS_NORMAL | SUCCS_SKIP_TO_LOOP_EXITS)
      {
	basic_block bb = BLOCK_FOR_INSN (insn);

	if (!BB_LV_SET_VALID_P (bb))
	  compute_live (insn);
      }
  }

  /* Emulate the Haifa scheduler for bundling.  */
  if (reload_completed)
    sel_region_target_finish (reset_sched_cycles_p);

  sel_finish_global_and_expr ();

  bitmap_clear (forced_ebb_heads);

  free_nop_vinsn ();

  finish_deps_global ();
  sched_finish_luids ();
  h_d_i_d.release ();

  sel_finish_bbs ();
  BITMAP_FREE (blocks_to_reschedule);

  sel_unregister_cfg_hooks ();

  max_issue_size = 0;
}


/* Functions that implement the scheduler driver.  */

/* Schedule a parallel instruction group on each of FENCES.  MAX_SEQNO
   is the current maximum seqno.  SCHEDULED_INSNS_TAILPP is the list
   of insns scheduled -- these would be postprocessed later.  */
static void
schedule_on_fences (flist_t fences, int max_seqno,
                    ilist_t **scheduled_insns_tailpp)
{
  flist_t old_fences = fences;

  if (sched_verbose >= 1)
    {
      sel_print ("\nScheduling on fences: ");
      dump_flist (fences);
      sel_print ("\n");
    }

  scheduled_something_on_previous_fence = false;
  for (; fences; fences = FLIST_NEXT (fences))
    {
      fence_t fence = NULL;
      int seqno = 0;
      flist_t fences2;
      bool first_p = true;

      /* Choose the next fence group to schedule.
         The fact that insn can be scheduled only once
         on the cycle is guaranteed by two properties:
         1. seqnos of parallel groups decrease with each iteration.
         2. If is_ineligible_successor () sees the larger seqno, it
         checks if candidate insn is_in_current_fence_p ().  */
      for (fences2 = old_fences; fences2; fences2 = FLIST_NEXT (fences2))
        {
          fence_t f = FLIST_FENCE (fences2);

          if (!FENCE_PROCESSED_P (f))
            {
              int i = INSN_SEQNO (FENCE_INSN (f));

              if (first_p || i > seqno)
                {
                  seqno = i;
                  fence = f;
                  first_p = false;
                }
              else
                /* ??? Seqnos of different groups should be different.  */
                gcc_assert (1 || i != seqno);
            }
        }

      gcc_assert (fence);

      /* As FENCE is nonnull, SEQNO is initialized.  */
      seqno -= max_seqno + 1;
      fill_insns (fence, seqno, scheduled_insns_tailpp);
      FENCE_PROCESSED_P (fence) = true;
    }

  /* All av_sets are invalidated by GLOBAL_LEVEL increase, thus we
     don't need to keep bookkeeping-invalidated and target-unavailable
     vinsns any more.  */
  vinsn_vec_clear (&vec_bookkeeping_blocked_vinsns);
  vinsn_vec_clear (&vec_target_unavailable_vinsns);
}

/* Calculate MIN_SEQNO and MAX_SEQNO.  */
static void
find_min_max_seqno (flist_t fences, int *min_seqno, int *max_seqno)
{
  *min_seqno = *max_seqno = INSN_SEQNO (FENCE_INSN (FLIST_FENCE (fences)));

  /* The first element is already processed.  */
  while ((fences = FLIST_NEXT (fences)))
    {
      int seqno = INSN_SEQNO (FENCE_INSN (FLIST_FENCE (fences)));

      if (*min_seqno > seqno)
        *min_seqno = seqno;
      else if (*max_seqno < seqno)
        *max_seqno = seqno;
    }
}

/* Calculate new fences from FENCES.  Write the current time to PTIME.  */
static flist_t
calculate_new_fences (flist_t fences, int orig_max_seqno, int *ptime)
{
  flist_t old_fences = fences;
  struct flist_tail_def _new_fences, *new_fences = &_new_fences;
  int max_time = 0;

  flist_tail_init (new_fences);
  for (; fences; fences = FLIST_NEXT (fences))
    {
      fence_t fence = FLIST_FENCE (fences);
      insn_t insn;

      if (!FENCE_BNDS (fence))
        {
          /* This fence doesn't have any successors.  */
          if (!FENCE_SCHEDULED_P (fence))
            {
              /* Nothing was scheduled on this fence.  */
              int seqno;

              insn = FENCE_INSN (fence);
              seqno = INSN_SEQNO (insn);
              gcc_assert (seqno > 0 && seqno <= orig_max_seqno);

              if (sched_verbose >= 1)
                sel_print ("Fence %d[%d] has not changed\n",
                           INSN_UID (insn),
                           BLOCK_NUM (insn));
              move_fence_to_fences (fences, new_fences);
            }
        }
      else
        extract_new_fences_from (fences, new_fences, orig_max_seqno);
      max_time = MAX (max_time, FENCE_CYCLE (fence));
    }

  flist_clear (&old_fences);
  *ptime = max_time;
  return FLIST_TAIL_HEAD (new_fences);
}

/* Update seqnos of insns given by PSCHEDULED_INSNS.  MIN_SEQNO and MAX_SEQNO
   are the miminum and maximum seqnos of the group, HIGHEST_SEQNO_IN_USE is
   the highest seqno used in a region.  Return the updated highest seqno.  */
static int
update_seqnos_and_stage (int min_seqno, int max_seqno,
                         int highest_seqno_in_use,
                         ilist_t *pscheduled_insns)
{
  int new_hs;
  ilist_iterator ii;
  insn_t insn;

  /* Actually, new_hs is the seqno of the instruction, that was
     scheduled first (i.e. it is the first one in SCHEDULED_INSNS).  */
  if (*pscheduled_insns)
    {
      new_hs = (INSN_SEQNO (ILIST_INSN (*pscheduled_insns))
                + highest_seqno_in_use + max_seqno - min_seqno + 2);
      gcc_assert (new_hs > highest_seqno_in_use);
    }
  else
    new_hs = highest_seqno_in_use;

  FOR_EACH_INSN (insn, ii, *pscheduled_insns)
    {
      gcc_assert (INSN_SEQNO (insn) < 0);
      INSN_SEQNO (insn) += highest_seqno_in_use + max_seqno - min_seqno + 2;
      gcc_assert (INSN_SEQNO (insn) <= new_hs);

      /* When not pipelining, purge unneeded insn info on the scheduled insns.
         For example, having reg_last array of INSN_DEPS_CONTEXT in memory may
         require > 1GB of memory e.g. on limit-fnargs.c.  */
      if (! pipelining_p)
        free_data_for_scheduled_insn (insn);
    }

  ilist_clear (pscheduled_insns);
  global_level++;

  return new_hs;
}

/* The main driver for scheduling a region.  This function is responsible
   for correct propagation of fences (i.e. scheduling points) and creating
   a group of parallel insns at each of them.  It also supports
   pipelining.  ORIG_MAX_SEQNO is the maximal seqno before this pass
   of scheduling.  */
static void
sel_sched_region_2 (int orig_max_seqno)
{
  int highest_seqno_in_use = orig_max_seqno;
  int max_time = 0;

  stat_bookkeeping_copies = 0;
  stat_insns_needed_bookkeeping = 0;
  stat_renamed_scheduled = 0;
  stat_substitutions_total = 0;
  num_insns_scheduled = 0;

  while (fences)
    {
      int min_seqno, max_seqno;
      ilist_t scheduled_insns = NULL;
      ilist_t *scheduled_insns_tailp = &scheduled_insns;

      find_min_max_seqno (fences, &min_seqno, &max_seqno);
      schedule_on_fences (fences, max_seqno, &scheduled_insns_tailp);
      fences = calculate_new_fences (fences, orig_max_seqno, &max_time);
      highest_seqno_in_use = update_seqnos_and_stage (min_seqno, max_seqno,
                                                      highest_seqno_in_use,
                                                      &scheduled_insns);
    }

  if (sched_verbose >= 1)
    {
      sel_print ("Total scheduling time: %d cycles\n", max_time);
      sel_print ("Scheduled %d bookkeeping copies, %d insns needed "
		 "bookkeeping, %d insns renamed, %d insns substituted\n",
		 stat_bookkeeping_copies,
		 stat_insns_needed_bookkeeping,
		 stat_renamed_scheduled,
		 stat_substitutions_total);
    }
}

/* Schedule a region.  When pipelining, search for possibly never scheduled
   bookkeeping code and schedule it.  Reschedule pipelined code without
   pipelining after.  */
static void
sel_sched_region_1 (void)
{
  int orig_max_seqno;

  /* Remove empty blocks that might be in the region from the beginning.  */
  purge_empty_blocks ();

  orig_max_seqno = init_seqno (NULL, NULL);
  gcc_assert (orig_max_seqno >= 1);

  /* When pipelining outer loops, create fences on the loop header,
     not preheader.  */
  fences = NULL;
  if (current_loop_nest)
    init_fences (BB_END (EBB_FIRST_BB (0)));
  else
    init_fences (bb_note (EBB_FIRST_BB (0)));
  global_level = 1;

  sel_sched_region_2 (orig_max_seqno);

  gcc_assert (fences == NULL);

  if (pipelining_p)
    {
      int i;
      basic_block bb;
      struct flist_tail_def _new_fences;
      flist_tail_t new_fences = &_new_fences;
      bool do_p = true;

      pipelining_p = false;
      max_ws = MIN (max_ws, issue_rate * 3 / 2);
      bookkeeping_p = false;
      enable_schedule_as_rhs_p = false;

      /* Schedule newly created code, that has not been scheduled yet.  */
      do_p = true;

      while (do_p)
        {
          do_p = false;

          for (i = 0; i < current_nr_blocks; i++)
            {
              basic_block bb = EBB_FIRST_BB (i);

              if (bitmap_bit_p (blocks_to_reschedule, bb->index))
                {
                  if (! bb_ends_ebb_p (bb))
                    bitmap_set_bit (blocks_to_reschedule, bb_next_bb (bb)->index);
                  if (sel_bb_empty_p (bb))
                    {
                      bitmap_clear_bit (blocks_to_reschedule, bb->index);
                      continue;
                    }
                  clear_outdated_rtx_info (bb);
                  if (sel_insn_is_speculation_check (BB_END (bb))
                      && JUMP_P (BB_END (bb)))
                    bitmap_set_bit (blocks_to_reschedule,
                                    BRANCH_EDGE (bb)->dest->index);
                }
              else if (! sel_bb_empty_p (bb)
                       && INSN_SCHED_TIMES (sel_bb_head (bb)) <= 0)
                bitmap_set_bit (blocks_to_reschedule, bb->index);
            }

          for (i = 0; i < current_nr_blocks; i++)
            {
              bb = EBB_FIRST_BB (i);

              /* While pipelining outer loops, skip bundling for loop
                 preheaders.  Those will be rescheduled in the outer
                 loop.  */
              if (sel_is_loop_preheader_p (bb))
                {
                  clear_outdated_rtx_info (bb);
                  continue;
                }

              if (bitmap_bit_p (blocks_to_reschedule, bb->index))
                {
                  flist_tail_init (new_fences);

                  orig_max_seqno = init_seqno (blocks_to_reschedule, bb);

                  /* Mark BB as head of the new ebb.  */
                  bitmap_set_bit (forced_ebb_heads, bb->index);

                  gcc_assert (fences == NULL);

                  init_fences (bb_note (bb));

                  sel_sched_region_2 (orig_max_seqno);

                  do_p = true;
                  break;
                }
            }
        }
    }
}

/* Schedule the RGN region.  */
void
sel_sched_region (int rgn)
{
  bool schedule_p;
  bool reset_sched_cycles_p;

  if (sel_region_init (rgn))
    return;

  if (sched_verbose >= 1)
    sel_print ("Scheduling region %d\n", rgn);

  schedule_p = (!sched_is_disabled_for_current_region_p ()
                && dbg_cnt (sel_sched_region_cnt));
  reset_sched_cycles_p = pipelining_p;
  if (schedule_p)
    sel_sched_region_1 ();
  else
    {
      /* Schedule always selecting the next insn to make the correct data
	 for bundling or other later passes.  */
      pipelining_p = false;
      force_next_insn = 1;
      sel_sched_region_1 ();
      force_next_insn = 0;
    }
  reset_sched_cycles_p = pipelining_p;
  sel_region_finish (reset_sched_cycles_p);
}

/* Perform global init for the scheduler.  */
static void
sel_global_init (void)
{
  /* Remove empty blocks: their presence can break assumptions elsewhere,
     e.g. the logic to invoke update_liveness_on_insn in sel_region_init.  */
  cleanup_cfg (0);

  calculate_dominance_info (CDI_DOMINATORS);
  alloc_sched_pools ();

  /* Setup the infos for sched_init.  */
  sel_setup_sched_infos ();
  setup_sched_dump ();

  sched_rgn_init (false);
  sched_init ();

  sched_init_bbs ();
  /* Reset AFTER_RECOVERY if it has been set by the 1st scheduler pass.  */
  after_recovery = 0;
  can_issue_more = issue_rate;

  sched_extend_target ();
  sched_deps_init (true);
  setup_nop_and_exit_insns ();
  sel_extend_global_bb_info ();
  init_lv_sets ();
  init_hard_regs_data ();
}

/* Free the global data of the scheduler.  */
static void
sel_global_finish (void)
{
  free_bb_note_pool ();
  free_lv_sets ();
  sel_finish_global_bb_info ();

  free_regset_pool ();
  free_nop_and_exit_insns ();

  sched_rgn_finish ();
  sched_deps_finish ();
  sched_finish ();

  if (current_loops)
    sel_finish_pipelining ();

  free_sched_pools ();
  free_dominance_info (CDI_DOMINATORS);
}

/* Return true when we need to skip selective scheduling.  Used for debugging.  */
bool
maybe_skip_selective_scheduling (void)
{
  return ! dbg_cnt (sel_sched_cnt);
}

/* The entry point.  */
void
run_selective_scheduling (void)
{
  int rgn;

  if (n_basic_blocks_for_fn (cfun) == NUM_FIXED_BLOCKS)
    return;

  sel_global_init ();

  for (rgn = 0; rgn < nr_regions; rgn++)
    sel_sched_region (rgn);

  sel_global_finish ();
}

#endif
