/* Early (pre-RA) rematerialization
   Copyright (C) 2017-2021 Free Software Foundation, Inc.

This file is part of GCC.

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

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

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

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "rtl.h"
#include "df.h"
#include "tree-pass.h"
#include "memmodel.h"
#include "emit-rtl.h"
#include "insn-config.h"
#include "recog.h"
/* FIXME: The next two are only needed for gen_move_insn.  */
#include "tree.h"
#include "expr.h"
#include "target.h"
#include "inchash.h"
#include "rtlhash.h"
#include "print-rtl.h"
#include "rtl-iter.h"
#include "regs.h"
#include "function-abi.h"

/* This pass runs before register allocation and implements an aggressive
   form of rematerialization.  It looks for pseudo registers R of mode M
   for which:

     (a) there are no call-preserved registers of mode M; and
     (b) spilling R to the stack is expensive.

   The assumption is that it's better to recompute R after each call instead
   of spilling it, even if this extends the live ranges of other registers.

   The motivating example for which these conditions hold are AArch64 SVE
   vectors and predicates.  Spilling them to the stack makes the frame
   variable-sized, which we'd like to avoid if possible.  It's also very
   rare for SVE values to be "naturally" live across a call: usually this
   happens as a result of CSE or other code motion.

   The pass is split into the following phases:

   Collection phase
   ================

   First we go through all pseudo registers looking for any that meet
   the conditions above.  For each such register R, we go through each
   instruction that defines R to see whether any of them are suitable
   rematerialization candidates.  If at least one is, we treat all the
   instructions that define R as candidates, but record which ones are
   not in fact suitable.  These unsuitable candidates exist only for the
   sake of calculating reaching definitions (see below).

   A "candidate" is a single instruction that we want to rematerialize
   and a "candidate register" is a register that is set by at least one
   candidate.

   Candidate sorting
   =================

   Next we sort the candidates based on the cfg postorder, so that if
   candidate C1 uses candidate C2, C1 has a lower index than C2.
   This is useful when iterating through candidate bitmaps.

   Reaching definition calculation
   ===============================

   We then compute standard reaching-definition sets for each candidate.
   Each set specifies which candidates might provide the current definition
   of a live candidate register.

   From here on, a candidate C is "live" at a point P if the candidate
   register defined by C is live at P and if C's definition reaches P.
   An instruction I "uses" a candidate C if I takes the register defined by
   C as input and if C is one of the reaching definitions of that register.

   Candidate validation and value numbering
   ========================================

   Next we simultaneously decide which candidates are valid and look
   for candidates that are equivalent to each other, assigning numbers
   to each unique candidate value.  A candidate C is invalid if:

     (a) C uses an invalid candidate;

     (b) there is a cycle of candidate uses involving C; or

     (c) C takes a candidate register R as input and the reaching
         definitions of R do not have the same value number.

   We assign a "representative" candidate C to each value number and from
   here on replace references to other candidates with that value number
   with references to C.  It is then only possible to rematerialize a
   register R at point P if (after this replacement) there is a single
   reaching definition of R at P.

   Local phase
   ===========

   During this phase we go through each block and look for cases in which:

     (a) an instruction I comes between two call instructions CI1 and CI2;

     (b) I uses a candidate register R;

     (c) a candidate C provides the only reaching definition of R; and

     (d) C does not come between CI1 and I.

   We then emit a copy of C after CI1, as well as the transitive closure
   TC of the candidates used by C.  The copies of TC might use the original
   candidate registers or new temporary registers, depending on circumstances.

   For example, if elsewhere we have:

       C3: R3 <- f3 (...)
	   ...
       C2: R2 <- f2 (...)
	   ...
       C1: R1 <- f1 (R2, R3, ...)  // uses C2 and C3

   then for a block containing:

      CI1: call
	   ...
	I: use R1  // uses C1
	   ...
      CI2: call

   we would emit:

      CI1: call
      C3': R3' <- f3 (...)
      C2': R2' <- f2 (...)
      C1': R1 <- f1 (R2', R3', ...)
	   ...
	I: use R1
	   ...
      CI2: call

   where R2' and R3' might be fresh registers.  If instead we had:

      CI1: call
	   ...
       I1: use R1  // uses C1
	   ...
       I2: use R3  // uses C3
	   ...
      CI2: call

   we would keep the original R3:

      CI1: call
      C3': R3 <- f3 (...)
      C2': R2' <- f2 (...)
      C1': R1 <- f1 (R2', R3, ...)
	   ...
       I1: use R1  // uses C1
	   ...
       I2: use R3  // uses C3
	   ...
      CI2: call

   We also record the last call in each block (if any) and compute:

     rd_after_call:
       The set of candidates that either (a) are defined outside the block
       and are live after the last call or (b) are defined within the block
       and reach the end of the last call.  (We don't track whether the
       latter values are live or not.)

     required_after_call:
       The set of candidates that need to be rematerialized after the
       last call in order to satisfy uses in the block itself.

     required_in:
       The set of candidates that are live on entry to the block and are
       used without an intervening call.

   In addition, we compute the initial values of the sets required by
   the global phase below.

   Global phase
   ============

   We next compute a maximal solution to the following availability
   problem:

     available_in:
       The set of candidates that are live on entry to a block and can
       be used at that point without rematerialization.

     available_out:
       The set of candidates that are live on exit from a block and can
       be used at that point without rematerialization.

     available_locally:
       The subset of available_out that is due to code in the block itself.
       It contains candidates that are defined or used in the block and
       not invalidated by a later call.

   We then go through each block B and look for an appropriate place
   to insert copies of required_in - available_in.  Conceptually we
   start by placing the copies at the head of B, but then move the
   copy of a candidate C to predecessors if:

     (a) that seems cheaper;

     (b) there is more than one reaching definition of C's register at
	 the head of B; or

     (c) copying C would clobber a hard register that is live on entry to B.

   Moving a copy of C to a predecessor block PB involves:

     (1) adding C to PB's required_after_call, if PB contains a call; or

     (2) adding C PB's required_in otherwise.

   C is then available on output from each PB and on input to B.

   Once all this is done, we emit instructions for the final required_in
   and required_after_call sets.  */

namespace {

/* An invalid candidate index, used to indicate that there is more than
   one reaching definition.  */
const unsigned int MULTIPLE_CANDIDATES = -1U;

/* Pass-specific information about one basic block.  */
struct remat_block_info {
  /* The last call instruction in the block.  */
  rtx_insn *last_call;

  /* The set of candidates that are live on entry to the block.  NULL is
     equivalent to an empty set.  */
  bitmap rd_in;

  /* The set of candidates that are live on exit from the block.  This might
     reuse rd_in.  NULL is equivalent to an empty set.  */
  bitmap rd_out;

  /* The subset of RD_OUT that comes from local definitions.  NULL is
     equivalent to an empty set.  */
  bitmap rd_gen;

  /* The set of candidates that the block invalidates (because it defines
     the register to something else, or because the register's value is
     no longer important).  NULL is equivalent to an empty set.  */
  bitmap rd_kill;

  /* The set of candidates that either (a) are defined outside the block
     and are live after LAST_CALL or (b) are defined within the block
     and reach the instruction after LAST_CALL.  (We don't track whether
     the latter values are live or not.)

     Only used if LAST_CALL is nonnull.  NULL is equivalent to an
     empty set.  */
  bitmap rd_after_call;

  /* Candidates that are live and available without rematerialization
     on entry to the block.  NULL is equivalent to an empty set.  */
  bitmap available_in;

  /* Candidates that become available without rematerialization within the
     block, and remain so on exit.  NULL is equivalent to an empty set.  */
  bitmap available_locally;

  /* Candidates that are available without rematerialization on exit from
     the block.  This might reuse available_in or available_locally.  */
  bitmap available_out;

  /* Candidates that need to be rematerialized either at the start of the
     block or before entering the block.  */
  bitmap required_in;

  /* Candidates that need to be rematerialized after LAST_CALL.
     Only used if LAST_CALL is nonnull.  */
  bitmap required_after_call;

  /* The number of candidates in the block.  */
  unsigned int num_candidates;

  /* The earliest candidate in the block (i.e. the one with the
     highest index).  Only valid if NUM_CANDIDATES is nonzero.  */
  unsigned int first_candidate;

  /* The best (lowest) execution frequency for rematerializing REQUIRED_IN.
     This is the execution frequency of the block if LOCAL_REMAT_CHEAPER_P,
     otherwise it is the sum of the execution frequencies of whichever
     predecessor blocks would do the rematerialization.  */
  int remat_frequency;

  /* True if the block ends with an abnormal call.  */
  unsigned int abnormal_call_p : 1;

  /* Used to record whether a graph traversal has visited this block.  */
  unsigned int visited_p : 1;

  /* True if we have calculated REMAT_FREQUENCY.  */
  unsigned int remat_frequency_valid_p : 1;

  /* True if it is cheaper to rematerialize candidates at the start of
     the block, rather than moving them to predecessor blocks.  */
  unsigned int local_remat_cheaper_p : 1;
};

/* Information about a group of candidates with the same value number.  */
struct remat_equiv_class {
  /* The candidates that have the same value number.  */
  bitmap members;

  /* The candidate that was first added to MEMBERS.  */
  unsigned int earliest;

  /* The candidate that represents the others.  This is always the one
     with the highest index.  */
  unsigned int representative;
};

/* Information about an instruction that we might want to rematerialize.  */
struct remat_candidate {
  /* The pseudo register that the instruction sets.  */
  unsigned int regno;

  /* A temporary register used when rematerializing uses of this candidate,
     if REGNO doesn't have the right value or isn't worth using.  */
  unsigned int copy_regno;

  /* True if we intend to rematerialize this instruction by emitting
     a move of a constant into REGNO, false if we intend to emit a
     copy of the original instruction.  */
  unsigned int constant_p : 1;

  /* True if we still think it's possible to rematerialize INSN.  */
  unsigned int can_copy_p : 1;

  /* Used to record whether a graph traversal has visited this candidate.  */
  unsigned int visited_p : 1;

  /* True if we have verified that it's possible to rematerialize INSN.
     Once this is true, both it and CAN_COPY_P remain true.  */
  unsigned int validated_p : 1;

  /* True if we have "stabilized" INSN, i.e. ensured that all non-candidate
     registers read by INSN will have the same value when rematerializing INSN.
     Only ever true if CAN_COPY_P.  */
  unsigned int stabilized_p : 1;

  /* Hash value used for value numbering.  */
  hashval_t hash;

  /* The instruction that sets REGNO.  */
  rtx_insn *insn;

  /* If CONSTANT_P, the value that should be moved into REGNO when
     rematerializing, otherwise the pattern of the instruction that
     should be used.  */
  rtx remat_rtx;

  /* The set of candidates that INSN takes as input.  NULL is equivalent
     to the empty set.  All candidates in this set have a higher index
     than the current candidate.  */
  bitmap uses;

  /* The set of hard registers that would be clobbered by rematerializing
     the candidate, including (transitively) all those that would be
     clobbered by rematerializing USES.  */
  bitmap clobbers;

  /* The equivalence class to which the candidate belongs, or null if none.  */
  remat_equiv_class *equiv_class;
};

/* Hash functions used for value numbering.  */
struct remat_candidate_hasher : nofree_ptr_hash <remat_candidate>
{
  typedef value_type compare_type;
  static hashval_t hash (const remat_candidate *);
  static bool equal (const remat_candidate *, const remat_candidate *);
};

/* Main class for this pass.  */
class early_remat {
public:
  early_remat (function *, sbitmap);
  ~early_remat ();

  void run (void);

private:
  bitmap alloc_bitmap (void);
  bitmap get_bitmap (bitmap *);
  void init_temp_bitmap (bitmap *);
  void copy_temp_bitmap (bitmap *, bitmap *);

  void dump_insn_id (rtx_insn *);
  void dump_candidate_bitmap (bitmap);
  void dump_all_candidates (void);
  void dump_edge_list (basic_block, bool);
  void dump_block_info (basic_block);
  void dump_all_blocks (void);

  bool interesting_regno_p (unsigned int);
  remat_candidate *add_candidate (rtx_insn *, unsigned int, bool);
  bool maybe_add_candidate (rtx_insn *, unsigned int);
  bool collect_candidates (void);
  void init_block_info (void);
  void sort_candidates (void);
  void finalize_candidate_indices (void);
  void record_equiv_candidates (unsigned int, unsigned int);
  static bool rd_confluence_n (edge);
  static bool rd_transfer (int);
  void compute_rd (void);
  unsigned int canon_candidate (unsigned int);
  void canon_bitmap (bitmap *);
  unsigned int resolve_reaching_def (bitmap);
  bool check_candidate_uses (unsigned int);
  void compute_clobbers (unsigned int);
  void assign_value_number (unsigned int);
  void decide_candidate_validity (void);
  void restrict_remat_for_unavail_regs (bitmap, const_bitmap);
  void restrict_remat_for_call (bitmap, rtx_insn *);
  bool stable_use_p (unsigned int);
  void emit_copy_before (unsigned int, rtx, rtx);
  void stabilize_pattern (unsigned int);
  void replace_dest_with_copy (unsigned int);
  void stabilize_candidate_uses (unsigned int, bitmap, bitmap, bitmap,
				 bitmap);
  void emit_remat_insns (bitmap, bitmap, bitmap, rtx_insn *);
  bool set_available_out (remat_block_info *);
  void process_block (basic_block);
  void local_phase (void);
  static bool avail_confluence_n (edge);
  static bool avail_transfer (int);
  void compute_availability (void);
  void unshare_available_sets (remat_block_info *);
  bool can_move_across_edge_p (edge);
  bool local_remat_cheaper_p (unsigned int);
  bool need_to_move_candidate_p (unsigned int, unsigned int);
  void compute_minimum_move_set (unsigned int, bitmap);
  void move_to_predecessors (unsigned int, bitmap, bitmap);
  void choose_rematerialization_points (void);
  void emit_remat_insns_for_block (basic_block);
  void global_phase (void);

  /* The function that we're optimizing.  */
  function *m_fn;

  /* The modes that we want to rematerialize.  */
  sbitmap m_selected_modes;

  /* All rematerialization candidates, identified by their index into the
     vector.  */
  auto_vec<remat_candidate> m_candidates;

  /* The set of candidate registers.  */
  bitmap_head m_candidate_regnos;

  /* Temporary sets.  */
  bitmap_head m_tmp_bitmap;
  bitmap m_available;
  bitmap m_required;

  /* Information about each basic block.  */
  auto_vec<remat_block_info> m_block_info;

  /* A mapping from register numbers to the set of associated candidates.
     Only valid for registers in M_CANDIDATE_REGNOS.  */
  auto_vec<bitmap> m_regno_to_candidates;

  /* An obstack used for allocating bitmaps, so that we can free them all
     in one go.  */
  bitmap_obstack m_obstack;

  /* A hash table of candidates used for value numbering.  If a candidate
     in the table is in an equivalence class, the candidate is marked as
     the earliest member of the class.  */
  hash_table<remat_candidate_hasher> m_value_table;

  /* Used temporarily by callback functions.  */
  static early_remat *er;
};

}

early_remat *early_remat::er;

/* rtx_equal_p_cb callback that treats any two SCRATCHes as equal.
   This allows us to compare two copies of a pattern, even though their
   SCRATCHes are always distinct.  */

static int
scratch_equal (const_rtx *x, const_rtx *y, rtx *nx, rtx *ny)
{
  if (GET_CODE (*x) == SCRATCH && GET_CODE (*y) == SCRATCH)
    {
      *nx = const0_rtx;
      *ny = const0_rtx;
      return 1;
    }
  return 0;
}

/* Hash callback functions for remat_candidate.  */

hashval_t
remat_candidate_hasher::hash (const remat_candidate *cand)
{
  return cand->hash;
}

bool
remat_candidate_hasher::equal (const remat_candidate *cand1,
			       const remat_candidate *cand2)
{
  return (cand1->regno == cand2->regno
	  && cand1->constant_p == cand2->constant_p
	  && (cand1->constant_p
	      ? rtx_equal_p (cand1->remat_rtx, cand2->remat_rtx)
	      : rtx_equal_p_cb (cand1->remat_rtx, cand2->remat_rtx,
				scratch_equal))
	  && (!cand1->uses || bitmap_equal_p (cand1->uses, cand2->uses)));
}

/* Return true if B is null or empty.  */

inline bool
empty_p (bitmap b)
{
  return !b || bitmap_empty_p (b);
}

/* Allocate a new bitmap.  It will be automatically freed at the end of
   the pass.  */

inline bitmap
early_remat::alloc_bitmap (void)
{
  return bitmap_alloc (&m_obstack);
}

/* Initialize *PTR to an empty bitmap if it is currently null.  */

inline bitmap
early_remat::get_bitmap (bitmap *ptr)
{
  if (!*ptr)
    *ptr = alloc_bitmap ();
  return *ptr;
}

/* *PTR is either null or empty.  If it is null, initialize it to an
   empty bitmap.  */

inline void
early_remat::init_temp_bitmap (bitmap *ptr)
{
  if (!*ptr)
    *ptr = alloc_bitmap ();
  else
    gcc_checking_assert (bitmap_empty_p (*ptr));
}

/* Move *SRC to *DEST and leave *SRC empty.  */

inline void
early_remat::copy_temp_bitmap (bitmap *dest, bitmap *src)
{
  if (!empty_p (*src))
    {
      *dest = *src;
      *src = NULL;
    }
  else
    *dest = NULL;
}

/* Print INSN's identifier to the dump file.  */

void
early_remat::dump_insn_id (rtx_insn *insn)
{
  fprintf (dump_file, "%d[bb:%d]", INSN_UID (insn),
	   BLOCK_FOR_INSN (insn)->index);
}

/* Print candidate set CANDIDATES to the dump file, with a leading space.  */

void
early_remat::dump_candidate_bitmap (bitmap candidates)
{
  if (empty_p (candidates))
    {
      fprintf (dump_file, " none");
      return;
    }

  unsigned int cand_index;
  bitmap_iterator bi;
  EXECUTE_IF_SET_IN_BITMAP (candidates, 0, cand_index, bi)
    fprintf (dump_file, " %d", cand_index);
}

/* Print information about all candidates to the dump file.  */

void
early_remat::dump_all_candidates (void)
{
  fprintf (dump_file, "\n;; Candidates:\n;;\n");
  fprintf (dump_file, ";; %5s %5s %8s %s\n", "#", "reg", "mode", "insn");
  fprintf (dump_file, ";; %5s %5s %8s %s\n", "=", "===", "====", "====");
  unsigned int cand_index;
  remat_candidate *cand;
  FOR_EACH_VEC_ELT (m_candidates, cand_index, cand)
    {
      fprintf (dump_file, ";; %5d %5d %8s ", cand_index, cand->regno,
	       GET_MODE_NAME (GET_MODE (regno_reg_rtx[cand->regno])));
      dump_insn_id (cand->insn);
      if (!cand->can_copy_p)
	fprintf (dump_file, "   -- can't copy");
      fprintf (dump_file, "\n");
    }

  fprintf (dump_file, "\n;; Register-to-candidate mapping:\n;;\n");
  unsigned int regno;
  bitmap_iterator bi;
  EXECUTE_IF_SET_IN_BITMAP (&m_candidate_regnos, 0, regno, bi)
    {
      fprintf (dump_file, ";; %5d:", regno);
      dump_candidate_bitmap (m_regno_to_candidates[regno]);
      fprintf (dump_file, "\n");
    }
}

/* Print the predecessors or successors of BB to the dump file, with a
   leading space.  DO_SUCC is true to print successors and false to print
   predecessors.  */

void
early_remat::dump_edge_list (basic_block bb, bool do_succ)
{
  edge e;
  edge_iterator ei;
  FOR_EACH_EDGE (e, ei, do_succ ? bb->succs : bb->preds)
    dump_edge_info (dump_file, e, TDF_NONE, do_succ);
}

/* Print information about basic block BB to the dump file.  */

void
early_remat::dump_block_info (basic_block bb)
{
  remat_block_info *info = &m_block_info[bb->index];
  fprintf (dump_file, ";;\n;; Block %d:", bb->index);
  int width = 25;

  fprintf (dump_file, "\n;;%*s:", width, "predecessors");
  dump_edge_list (bb, false);

  fprintf (dump_file, "\n;;%*s:", width, "successors");
  dump_edge_list (bb, true);

  fprintf (dump_file, "\n;;%*s: %d", width, "frequency",
	   bb->count.to_frequency (m_fn));

  if (info->last_call)
    fprintf (dump_file, "\n;;%*s: %d", width, "last call",
	     INSN_UID (info->last_call));

  if (!empty_p (info->rd_in))
    {
      fprintf (dump_file, "\n;;%*s:", width, "RD in");
      dump_candidate_bitmap (info->rd_in);
    }
  if (!empty_p (info->rd_kill))
    {
      fprintf (dump_file, "\n;;%*s:", width, "RD kill");
      dump_candidate_bitmap (info->rd_kill);
    }
  if (!empty_p (info->rd_gen))
    {
      fprintf (dump_file, "\n;;%*s:", width, "RD gen");
      dump_candidate_bitmap (info->rd_gen);
    }
  if (!empty_p (info->rd_after_call))
    {
      fprintf (dump_file, "\n;;%*s:", width, "RD after call");
      dump_candidate_bitmap (info->rd_after_call);
    }
  if (!empty_p (info->rd_out))
    {
      fprintf (dump_file, "\n;;%*s:", width, "RD out");
      if (info->rd_in == info->rd_out)
	fprintf (dump_file, " RD in");
      else
	dump_candidate_bitmap (info->rd_out);
    }
  if (!empty_p (info->available_in))
    {
      fprintf (dump_file, "\n;;%*s:", width, "available in");
      dump_candidate_bitmap (info->available_in);
    }
  if (!empty_p (info->available_locally))
    {
      fprintf (dump_file, "\n;;%*s:", width, "available locally");
      dump_candidate_bitmap (info->available_locally);
    }
  if (!empty_p (info->available_out))
    {
      fprintf (dump_file, "\n;;%*s:", width, "available out");
      if (info->available_in == info->available_out)
	fprintf (dump_file, " available in");
      else if (info->available_locally == info->available_out)
	fprintf (dump_file, " available locally");
      else
	dump_candidate_bitmap (info->available_out);
    }
  if (!empty_p (info->required_in))
    {
      fprintf (dump_file, "\n;;%*s:", width, "required in");
      dump_candidate_bitmap (info->required_in);
    }
  if (!empty_p (info->required_after_call))
    {
      fprintf (dump_file, "\n;;%*s:", width, "required after call");
      dump_candidate_bitmap (info->required_after_call);
    }
  fprintf (dump_file, "\n");
}

/* Print information about all basic blocks to the dump file.  */

void
early_remat::dump_all_blocks (void)
{
  basic_block bb;
  FOR_EACH_BB_FN (bb, m_fn)
    dump_block_info (bb);
}

/* Return true if REGNO is worth rematerializing.  */

bool
early_remat::interesting_regno_p (unsigned int regno)
{
  /* Ignore unused registers.  */
  rtx reg = regno_reg_rtx[regno];
  if (!reg || DF_REG_DEF_COUNT (regno) == 0)
    return false;

  /* Make sure the register has a mode that we want to rematerialize.  */
  if (!bitmap_bit_p (m_selected_modes, GET_MODE (reg)))
    return false;

  /* Ignore values that might sometimes be used uninitialized.  We could
     instead add dummy candidates for the entry block definition, and so
     handle uses that are definitely not uninitialized, but the combination
     of the two should be rare in practice.  */
  if (bitmap_bit_p (DF_LR_OUT (ENTRY_BLOCK_PTR_FOR_FN (m_fn)), regno))
    return false;

  return true;
}

/* Record the set of register REGNO in instruction INSN as a
   rematerialization candidate.  CAN_COPY_P is true unless we already
   know that rematerialization is impossible (in which case the candidate
   only exists for the reaching definition calculation).

   The candidate's index is not fixed at this stage.  */

remat_candidate *
early_remat::add_candidate (rtx_insn *insn, unsigned int regno,
			    bool can_copy_p)
{
  remat_candidate cand;
  memset (&cand, 0, sizeof (cand));
  cand.regno = regno;
  cand.insn = insn;
  cand.remat_rtx = PATTERN (insn);
  cand.can_copy_p = can_copy_p;
  m_candidates.safe_push (cand);

  bitmap_set_bit (&m_candidate_regnos, regno);

  return &m_candidates.last ();
}

/* Return true if we can rematerialize the set of register REGNO in
   instruction INSN, and add it as a candidate if so.  When returning
   false, print the reason to the dump file.  */

bool
early_remat::maybe_add_candidate (rtx_insn *insn, unsigned int regno)
{
#define FAILURE_FORMAT ";; Can't rematerialize set of reg %d in %d[bb:%d]: "
#define FAILURE_ARGS regno, INSN_UID (insn), BLOCK_FOR_INSN (insn)->index

  /* The definition must come from an ordinary instruction.  */
  basic_block bb = BLOCK_FOR_INSN (insn);
  if (!NONJUMP_INSN_P (insn)
      || (insn == BB_END (bb)
	  && has_abnormal_or_eh_outgoing_edge_p (bb)))
    {
      if (dump_file)
	fprintf (dump_file, FAILURE_FORMAT "insn alters control flow\n",
		 FAILURE_ARGS);
      return false;
    }

  /* Prefer to rematerialize constants directly -- it's much easier.  */
  machine_mode mode = GET_MODE (regno_reg_rtx[regno]);
  if (rtx note = find_reg_equal_equiv_note (insn))
    {
      rtx val = XEXP (note, 0);
      if (CONSTANT_P (val)
	  && targetm.legitimate_constant_p (mode, val))
	{
	  remat_candidate *cand = add_candidate (insn, regno, true);
	  cand->constant_p = true;
	  cand->remat_rtx = val;
	  return true;
	}
    }

  /* See whether the target has reasons to prevent a copy.  */
  if (targetm.cannot_copy_insn_p && targetm.cannot_copy_insn_p (insn))
    {
      if (dump_file)
	fprintf (dump_file, FAILURE_FORMAT "target forbids copying\n",
		 FAILURE_ARGS);
      return false;
    }

  /* We can't copy trapping instructions.  */
  rtx pat = PATTERN (insn);
  if (may_trap_p (pat))
    {
      if (dump_file)
	fprintf (dump_file, FAILURE_FORMAT "insn might trap\n", FAILURE_ARGS);
      return false;
    }

  /* We can't copy instructions that read memory, unless we know that
     the contents never change.  */
  subrtx_iterator::array_type array;
  FOR_EACH_SUBRTX (iter, array, pat, ALL)
    if (MEM_P (*iter) && !MEM_READONLY_P (*iter))
      {
	if (dump_file)
	  fprintf (dump_file, FAILURE_FORMAT "insn references non-constant"
		   " memory\n", FAILURE_ARGS);
	return false;
      }

  /* Check each defined register.  */
  df_ref ref;
  FOR_EACH_INSN_DEF (ref, insn)
    {
      unsigned int def_regno = DF_REF_REGNO (ref);
      if (def_regno == regno)
	{
	  /* Make sure the definition is write-only.  (Partial definitions,
	     such as setting the low part and clobbering the high part,
	     are otherwise OK.)  */
	  if (DF_REF_FLAGS_IS_SET (ref, DF_REF_READ_WRITE))
	    {
	      if (dump_file)
		fprintf (dump_file, FAILURE_FORMAT "destination is"
			 " read-modify-write\n", FAILURE_ARGS);
	      return false;
	    }
	}
      else
	{
	  /* The instruction can set additional registers, provided that
	     they're hard registers.  This is useful for instructions
	     that alter the condition codes.  */
	  if (!HARD_REGISTER_NUM_P (def_regno))
	    {
	      if (dump_file)
		fprintf (dump_file, FAILURE_FORMAT "insn also sets"
			 " pseudo reg %d\n", FAILURE_ARGS, def_regno);
	      return false;
	    }
	}
    }

  /* If the instruction uses fixed hard registers, check that those
     registers have the same value throughout the function.  If the
     instruction uses non-fixed hard registers, check that we can
     replace them with pseudos.  */
  FOR_EACH_INSN_USE (ref, insn)
    {
      unsigned int use_regno = DF_REF_REGNO (ref);
      if (HARD_REGISTER_NUM_P (use_regno) && fixed_regs[use_regno])
	{
	  if (rtx_unstable_p (DF_REF_REAL_REG (ref)))
	    {
	      if (dump_file)
		fprintf (dump_file, FAILURE_FORMAT "insn uses fixed hard reg"
			 " %d\n", FAILURE_ARGS, use_regno);
	      return false;
	    }
	}
      else if (HARD_REGISTER_NUM_P (use_regno))
	{
	  /* Allocate a dummy pseudo register and temporarily install it.
	     Make the register number depend on the mode, which should
	     provide enough sharing for match_dup while also weeding
	     out cases in which operands with different modes are
	     explicitly tied.  */
	  rtx *loc = DF_REF_REAL_LOC (ref);
	  unsigned int size = RTX_CODE_SIZE (REG);
	  rtx new_reg = (rtx) alloca (size);
	  memset (new_reg, 0, size);
	  PUT_CODE (new_reg, REG);
	  set_mode_and_regno (new_reg, GET_MODE (*loc),
			      LAST_VIRTUAL_REGISTER + 1 + GET_MODE (*loc));
	  validate_change (insn, loc, new_reg, 1);
	}
    }
  bool ok_p = verify_changes (0);
  cancel_changes (0);
  if (!ok_p)
    {
      if (dump_file)
	fprintf (dump_file, FAILURE_FORMAT "insn does not allow hard"
		 " register inputs to be replaced\n", FAILURE_ARGS);
      return false;
    }

#undef FAILURE_ARGS
#undef FAILURE_FORMAT

  add_candidate (insn, regno, true);
  return true;
}

/* Calculate the set of rematerialization candidates.  Return true if
   we find at least one.  */

bool
early_remat::collect_candidates (void)
{
  unsigned int nregs = DF_REG_SIZE (df);
  for (unsigned int regno = FIRST_PSEUDO_REGISTER; regno < nregs; ++regno)
    if (interesting_regno_p (regno))
      {
	/* Create candidates for all suitable definitions.  */
	bitmap_clear (&m_tmp_bitmap);
	unsigned int bad = 0;
	unsigned int id = 0;
	for (df_ref ref = DF_REG_DEF_CHAIN (regno); ref;
	     ref = DF_REF_NEXT_REG (ref))
	  {
	    rtx_insn *insn = DF_REF_INSN (ref);
	    if (maybe_add_candidate (insn, regno))
	      bitmap_set_bit (&m_tmp_bitmap, id);
	    else
	      bad += 1;
	    id += 1;
	  }

	/* If we found at least one suitable definition, add dummy
	   candidates for the rest, so that we can see which definitions
	   are live where.  */
	if (!bitmap_empty_p (&m_tmp_bitmap) && bad)
	  {
	    id = 0;
	    for (df_ref ref = DF_REG_DEF_CHAIN (regno); ref;
		 ref = DF_REF_NEXT_REG (ref))
	      {
		if (!bitmap_bit_p (&m_tmp_bitmap, id))
		  add_candidate (DF_REF_INSN (ref), regno, false);
		id += 1;
	      }
	  }
      }


  return !m_candidates.is_empty ();
}

/* Initialize the m_block_info array.  */

void
early_remat::init_block_info (void)
{
  unsigned int n_blocks = last_basic_block_for_fn (m_fn);
  m_block_info.safe_grow_cleared (n_blocks, true);
}

/* Maps basic block indices to their position in the post order.  */
static unsigned int *postorder_index;

/* Order remat_candidates X_IN and Y_IN according to the cfg postorder.  */

static int
compare_candidates (const void *x_in, const void *y_in)
{
  const remat_candidate *x = (const remat_candidate *) x_in;
  const remat_candidate *y = (const remat_candidate *) y_in;
  basic_block x_bb = BLOCK_FOR_INSN (x->insn);
  basic_block y_bb = BLOCK_FOR_INSN (y->insn);
  if (x_bb != y_bb)
    /* Make X and Y follow block postorder.  */
    return postorder_index[x_bb->index] - postorder_index[y_bb->index];

  /* Make X and Y follow a backward traversal of the containing block.  */
  return DF_INSN_LUID (y->insn) - DF_INSN_LUID (x->insn);
}

/* Sort the collected rematerialization candidates so that they follow
   cfg postorder.  */

void
early_remat::sort_candidates (void)
{
  /* Make sure the DF LUIDs are up-to-date for all the blocks we
     care about.  */
  bitmap_clear (&m_tmp_bitmap);
  unsigned int cand_index;
  remat_candidate *cand;
  FOR_EACH_VEC_ELT (m_candidates, cand_index, cand)
    {
      basic_block bb = BLOCK_FOR_INSN (cand->insn);
      if (bitmap_set_bit (&m_tmp_bitmap, bb->index))
	df_recompute_luids (bb);
    }

  /* Create a mapping from block numbers to their position in the
     postorder.  */
  unsigned int n_blocks = last_basic_block_for_fn (m_fn);
  int *postorder = df_get_postorder (DF_BACKWARD);
  unsigned int postorder_len = df_get_n_blocks (DF_BACKWARD);
  postorder_index = new unsigned int[n_blocks];
  for (unsigned int i = 0; i < postorder_len; ++i)
    postorder_index[postorder[i]] = i;

  m_candidates.qsort (compare_candidates);

  delete[] postorder_index;
}

/* Commit to the current candidate indices and initialize cross-references.  */

void
early_remat::finalize_candidate_indices (void)
{
  /* Create a bitmap for each candidate register.  */
  m_regno_to_candidates.safe_grow (max_reg_num (), true);
  unsigned int regno;
  bitmap_iterator bi;
  EXECUTE_IF_SET_IN_BITMAP (&m_candidate_regnos, 0, regno, bi)
    m_regno_to_candidates[regno] = alloc_bitmap ();

  /* Go through each candidate and record its index.  */
  unsigned int cand_index;
  remat_candidate *cand;
  FOR_EACH_VEC_ELT (m_candidates, cand_index, cand)
    {
      basic_block bb = BLOCK_FOR_INSN (cand->insn);
      remat_block_info *info = &m_block_info[bb->index];
      info->num_candidates += 1;
      info->first_candidate = cand_index;
      bitmap_set_bit (m_regno_to_candidates[cand->regno], cand_index);
    }
}

/* Record that candidates CAND1_INDEX and CAND2_INDEX are equivalent.
   CAND1_INDEX might already have an equivalence class, but CAND2_INDEX
   doesn't.  */

void
early_remat::record_equiv_candidates (unsigned int cand1_index,
				      unsigned int cand2_index)
{
  if (dump_file)
    fprintf (dump_file, ";; Candidate %d is equivalent to candidate %d\n",
	     cand2_index, cand1_index);

  remat_candidate *cand1 = &m_candidates[cand1_index];
  remat_candidate *cand2 = &m_candidates[cand2_index];
  gcc_checking_assert (!cand2->equiv_class);

  remat_equiv_class *ec = cand1->equiv_class;
  if (!ec)
    {
      ec = XOBNEW (&m_obstack.obstack, remat_equiv_class);
      ec->members = alloc_bitmap ();
      bitmap_set_bit (ec->members, cand1_index);
      ec->earliest = cand1_index;
      ec->representative = cand1_index;
      cand1->equiv_class = ec;
    }
  cand2->equiv_class = ec;
  bitmap_set_bit (ec->members, cand2_index);
  if (cand2_index > ec->representative)
    ec->representative = cand2_index;
}

/* Propagate information from the rd_out set of E->src to the rd_in set
   of E->dest, when computing global reaching definitions.  Return true
   if something changed.  */

bool
early_remat::rd_confluence_n (edge e)
{
  remat_block_info *src = &er->m_block_info[e->src->index];
  remat_block_info *dest = &er->m_block_info[e->dest->index];

  /* available_in temporarily contains the set of candidates whose
     registers are live on entry.  */
  if (empty_p (src->rd_out) || empty_p (dest->available_in))
    return false;

  return bitmap_ior_and_into (er->get_bitmap (&dest->rd_in),
			      src->rd_out, dest->available_in);
}

/* Propagate information from the rd_in set of block BB_INDEX to rd_out.
   Return true if something changed.  */

bool
early_remat::rd_transfer (int bb_index)
{
  remat_block_info *info = &er->m_block_info[bb_index];

  if (empty_p (info->rd_in))
    return false;

  if (empty_p (info->rd_kill))
    {
      gcc_checking_assert (empty_p (info->rd_gen));
      if (!info->rd_out)
	info->rd_out = info->rd_in;
      else
	gcc_checking_assert (info->rd_out == info->rd_in);
      /* Assume that we only get called if something changed.  */
      return true;
    }

  if (empty_p (info->rd_gen))
    return bitmap_and_compl (er->get_bitmap (&info->rd_out),
			     info->rd_in, info->rd_kill);

  return bitmap_ior_and_compl (er->get_bitmap (&info->rd_out), info->rd_gen,
			       info->rd_in, info->rd_kill);
}

/* Calculate the rd_* sets for each block.  */

void
early_remat::compute_rd (void)
{
  /* First calculate the rd_kill and rd_gen sets, using the fact
     that m_candidates is sorted in order of decreasing LUID.  */
  unsigned int cand_index;
  remat_candidate *cand;
  FOR_EACH_VEC_ELT_REVERSE (m_candidates, cand_index, cand)
    {
      rtx_insn *insn = cand->insn;
      basic_block bb = BLOCK_FOR_INSN (insn);
      remat_block_info *info = &m_block_info[bb->index];
      bitmap kill = m_regno_to_candidates[cand->regno];
      bitmap_ior_into (get_bitmap (&info->rd_kill), kill);
      if (bitmap_bit_p (DF_LR_OUT (bb), cand->regno))
	{
	  bitmap_and_compl_into (get_bitmap (&info->rd_gen), kill);
	  bitmap_set_bit (info->rd_gen, cand_index);
	}
    }

  /* Set up the initial values of the other sets.  */
  basic_block bb;
  FOR_EACH_BB_FN (bb, m_fn)
    {
      remat_block_info *info = &m_block_info[bb->index];
      unsigned int regno;
      bitmap_iterator bi;
      EXECUTE_IF_AND_IN_BITMAP (DF_LR_IN (bb), &m_candidate_regnos,
				0, regno, bi)
	{
	  /* Use available_in to record the set of candidates whose
	     registers are live on entry (i.e. a maximum bound on rd_in).  */
	  bitmap_ior_into (get_bitmap (&info->available_in),
			   m_regno_to_candidates[regno]);

	  /* Add registers that die in a block to the block's kill set,
	     so that we don't needlessly propagate them through the rest
	     of the function.  */
	  if (!bitmap_bit_p (DF_LR_OUT (bb), regno))
	    bitmap_ior_into (get_bitmap (&info->rd_kill),
			     m_regno_to_candidates[regno]);
	}

      /* Initialize each block's rd_out to the minimal set (the set of
	 local definitions).  */
      if (!empty_p (info->rd_gen))
	bitmap_copy (get_bitmap (&info->rd_out), info->rd_gen);
    }

  /* Iterate until we reach a fixed point.  */
  er = this;
  bitmap_clear (&m_tmp_bitmap);
  bitmap_set_range (&m_tmp_bitmap, 0, last_basic_block_for_fn (m_fn));
  df_simple_dataflow (DF_FORWARD, NULL, NULL, rd_confluence_n, rd_transfer,
		      &m_tmp_bitmap, df_get_postorder (DF_FORWARD),
		      df_get_n_blocks (DF_FORWARD));
  er = 0;

  /* Work out which definitions reach which candidates, again taking
     advantage of the candidate order.  */
  bitmap_head reaching;
  bitmap_initialize (&reaching, &m_obstack);
  basic_block old_bb = NULL;
  FOR_EACH_VEC_ELT_REVERSE (m_candidates, cand_index, cand)
    {
      bb = BLOCK_FOR_INSN (cand->insn);
      if (bb != old_bb)
	{
	  /* Get the definitions that reach the start of the new block.  */
	  remat_block_info *info = &m_block_info[bb->index];
	  if (info->rd_in)
	    bitmap_copy (&reaching, info->rd_in);
	  else
	    bitmap_clear (&reaching);
	  old_bb = bb;
	}
      else
	{
	  /* Process the definitions of the previous instruction.  */
	  bitmap kill = m_regno_to_candidates[cand[1].regno];
	  bitmap_and_compl_into (&reaching, kill);
	  bitmap_set_bit (&reaching, cand_index + 1);
	}

      if (cand->can_copy_p && !cand->constant_p)
	{
	  df_ref ref;
	  FOR_EACH_INSN_USE (ref, cand->insn)
	    {
	      unsigned int regno = DF_REF_REGNO (ref);
	      if (bitmap_bit_p (&m_candidate_regnos, regno))
		{
		  bitmap defs = m_regno_to_candidates[regno];
		  bitmap_and (&m_tmp_bitmap, defs, &reaching);
		  bitmap_ior_into (get_bitmap (&cand->uses), &m_tmp_bitmap);
		}
	    }
	}
    }
  bitmap_clear (&reaching);
}

/* If CAND_INDEX is in an equivalence class, return the representative
   of the class, otherwise return CAND_INDEX.  */

inline unsigned int
early_remat::canon_candidate (unsigned int cand_index)
{
  if (remat_equiv_class *ec = m_candidates[cand_index].equiv_class)
    return ec->representative;
  return cand_index;
}

/* Make candidate set *PTR refer to candidates using the representative
   of each equivalence class.  */

void
early_remat::canon_bitmap (bitmap *ptr)
{
  bitmap old_set = *ptr;
  if (empty_p (old_set))
    return;

  bitmap new_set = NULL;
  unsigned int old_index;
  bitmap_iterator bi;
  EXECUTE_IF_SET_IN_BITMAP (old_set, 0, old_index, bi)
    {
      unsigned int new_index = canon_candidate (old_index);
      if (old_index != new_index)
	{
	  if (!new_set)
	    {
	      new_set = alloc_bitmap ();
	      bitmap_copy (new_set, old_set);
	    }
	  bitmap_clear_bit (new_set, old_index);
	  bitmap_set_bit (new_set, new_index);
	}
    }
  if (new_set)
    {
      BITMAP_FREE (*ptr);
      *ptr = new_set;
    }
}

/* If the candidates in REACHING all have the same value, return the
   earliest instance of that value (i.e. the first one to be added
   to m_value_table), otherwise return MULTIPLE_CANDIDATES.  */

unsigned int
early_remat::resolve_reaching_def (bitmap reaching)
{
  unsigned int cand_index = bitmap_first_set_bit (reaching);
  if (remat_equiv_class *ec = m_candidates[cand_index].equiv_class)
    {
      if (!bitmap_intersect_compl_p (reaching, ec->members))
	return ec->earliest;
    }
  else if (bitmap_single_bit_set_p (reaching))
    return cand_index;

  return MULTIPLE_CANDIDATES;
}

/* Check whether all candidate registers used by candidate CAND_INDEX have
   unique definitions.  Return true if so, replacing the candidate's uses
   set with the appropriate form for value numbering.  */

bool
early_remat::check_candidate_uses (unsigned int cand_index)
{
  remat_candidate *cand = &m_candidates[cand_index];

  /* Process the uses for each register in turn.  */
  bitmap_head uses;
  bitmap_initialize (&uses, &m_obstack);
  bitmap_copy (&uses, cand->uses);
  bitmap uses_ec = alloc_bitmap ();
  while (!bitmap_empty_p (&uses))
    {
      /* Get the register for the lowest-indexed candidate remaining,
	 and the reaching definitions of that register.  */
      unsigned int first = bitmap_first_set_bit (&uses);
      unsigned int regno = m_candidates[first].regno;
      bitmap_and (&m_tmp_bitmap, &uses, m_regno_to_candidates[regno]);

      /* See whether all reaching definitions have the same value and if
	 so get the index of the first candidate we saw with that value.  */
      unsigned int def = resolve_reaching_def (&m_tmp_bitmap);
      if (def == MULTIPLE_CANDIDATES)
	{
	  if (dump_file)
	    fprintf (dump_file, ";; Removing candidate %d because there is"
		     " more than one reaching definition of reg %d\n",
		     cand_index, regno);
	  cand->can_copy_p = false;
	  break;
	}
      bitmap_set_bit (uses_ec, def);
      bitmap_and_compl_into (&uses, &m_tmp_bitmap);
    }
  BITMAP_FREE (cand->uses);
  cand->uses = uses_ec;
  return cand->can_copy_p;
}

/* Calculate the set of hard registers that would be clobbered by
   rematerializing candidate CAND_INDEX.  At this point the candidate's
   set of uses is final.  */

void
early_remat::compute_clobbers (unsigned int cand_index)
{
  remat_candidate *cand = &m_candidates[cand_index];
  if (cand->uses)
    {
      unsigned int use_index;
      bitmap_iterator bi;
      EXECUTE_IF_SET_IN_BITMAP (cand->uses, 0, use_index, bi)
	if (bitmap clobbers = m_candidates[use_index].clobbers)
	  bitmap_ior_into (get_bitmap (&cand->clobbers), clobbers);
    }

  df_ref ref;
  FOR_EACH_INSN_DEF (ref, cand->insn)
    {
      unsigned int def_regno = DF_REF_REGNO (ref);
      if (def_regno != cand->regno)
	bitmap_set_bit (get_bitmap (&cand->clobbers), def_regno);
    }
}

/* Mark candidate CAND_INDEX as validated and add it to the value table.  */

void
early_remat::assign_value_number (unsigned int cand_index)
{
  remat_candidate *cand = &m_candidates[cand_index];
  gcc_checking_assert (cand->can_copy_p && !cand->validated_p);

  compute_clobbers (cand_index);
  cand->validated_p = true;

  inchash::hash h;
  h.add_int (cand->regno);
  inchash::add_rtx (cand->remat_rtx, h);
  cand->hash = h.end ();

  remat_candidate **slot
    = m_value_table.find_slot_with_hash (cand, cand->hash, INSERT);
  if (!*slot)
    {
      *slot = cand;
      if (dump_file)
	fprintf (dump_file, ";; Candidate %d is not equivalent to"
		 " others seen so far\n", cand_index);
    }
  else
    record_equiv_candidates (*slot - m_candidates.address (), cand_index);
}

/* Make a final decision about which candidates are valid and assign
   value numbers to those that are.  */

void
early_remat::decide_candidate_validity (void)
{
  auto_vec<unsigned int, 16> stack;
  unsigned int cand1_index;
  remat_candidate *cand1;
  FOR_EACH_VEC_ELT_REVERSE (m_candidates, cand1_index, cand1)
    {
      if (!cand1->can_copy_p || cand1->validated_p)
	continue;

      if (empty_p (cand1->uses))
	{
	  assign_value_number (cand1_index);
	  continue;
	}

      stack.safe_push (cand1_index);
      while (!stack.is_empty ())
	{
	  unsigned int cand2_index = stack.last ();
	  unsigned int watermark = stack.length ();
	  remat_candidate *cand2 = &m_candidates[cand2_index];
	  if (!cand2->can_copy_p || cand2->validated_p)
	    {
	      stack.pop ();
	      continue;
	    }
	  cand2->visited_p = true;
	  unsigned int cand3_index;
	  bitmap_iterator bi;
	  EXECUTE_IF_SET_IN_BITMAP (cand2->uses, 0, cand3_index, bi)
	    {
	      remat_candidate *cand3 = &m_candidates[cand3_index];
	      if (!cand3->can_copy_p)
		{
		  if (dump_file)
		    fprintf (dump_file, ";; Removing candidate %d because"
			     " it uses removed candidate %d\n", cand2_index,
			     cand3_index);
		  cand2->can_copy_p = false;
		  break;
		}
	      if (!cand3->validated_p)
		{
		  if (empty_p (cand3->uses))
		    assign_value_number (cand3_index);
		  else if (cand3->visited_p)
		    {
		      if (dump_file)
			fprintf (dump_file, ";; Removing candidate %d"
				 " because its definition is cyclic\n",
				 cand2_index);
		      cand2->can_copy_p = false;
		      break;
		    }
		  else
		    stack.safe_push (cand3_index);
		}
	    }
	  if (!cand2->can_copy_p)
	    {
	      cand2->visited_p = false;
	      stack.truncate (watermark - 1);
	    }
	  else if (watermark == stack.length ())
	    {
	      cand2->visited_p = false;
	      if (check_candidate_uses (cand2_index))
		assign_value_number (cand2_index);
	      stack.pop ();
	    }
	}
    }

  /* Ensure that the candidates always use the same candidate index
     to refer to an equivalence class.  */
  FOR_EACH_VEC_ELT_REVERSE (m_candidates, cand1_index, cand1)
    if (cand1->can_copy_p && !empty_p (cand1->uses))
      {
	canon_bitmap (&cand1->uses);
	gcc_checking_assert (bitmap_first_set_bit (cand1->uses) > cand1_index);
      }
}

/* Remove any candidates in CANDIDATES that would clobber a register in
   UNAVAIL_REGS.  */

void
early_remat::restrict_remat_for_unavail_regs (bitmap candidates,
					      const_bitmap unavail_regs)
{
  bitmap_clear (&m_tmp_bitmap);
  unsigned int cand_index;
  bitmap_iterator bi;
  EXECUTE_IF_SET_IN_BITMAP (candidates, 0, cand_index, bi)
    {
      remat_candidate *cand = &m_candidates[cand_index];
      if (cand->clobbers
	  && bitmap_intersect_p (cand->clobbers, unavail_regs))
	bitmap_set_bit (&m_tmp_bitmap, cand_index);
    }
  bitmap_and_compl_into (candidates, &m_tmp_bitmap);
}

/* Remove any candidates in CANDIDATES that would clobber a register
   that is potentially live across CALL.  */

void
early_remat::restrict_remat_for_call (bitmap candidates, rtx_insn *call)
{
  /* We don't know whether partially-clobbered registers are live
     across the call or not, so assume that they are.  */
  bitmap_view<HARD_REG_SET> call_preserved_regs
    (~insn_callee_abi (call).full_reg_clobbers ());
  restrict_remat_for_unavail_regs (candidates, call_preserved_regs);
}

/* Assuming that every path reaching a point P contains a copy of a
   use U of REGNO, return true if another copy of U at P would have
   access to the same value of REGNO.  */

bool
early_remat::stable_use_p (unsigned int regno)
{
  /* Conservatively assume not for hard registers.  */
  if (HARD_REGISTER_NUM_P (regno))
    return false;

  /* See if REGNO has a single definition and is never used uninitialized.
     In this case the definition of REGNO dominates the common dominator
     of the uses U, which in turn dominates P.  */
  if (DF_REG_DEF_COUNT (regno) == 1
      && !bitmap_bit_p (DF_LR_OUT (ENTRY_BLOCK_PTR_FOR_FN (m_fn)), regno))
    return true;

  return false;
}

/* Emit a copy from register DEST to register SRC before candidate
   CAND_INDEX's instruction.  */

void
early_remat::emit_copy_before (unsigned int cand_index, rtx dest, rtx src)
{
  remat_candidate *cand = &m_candidates[cand_index];
  if (dump_file)
    {
      fprintf (dump_file, ";; Stabilizing insn ");
      dump_insn_id (cand->insn);
      fprintf (dump_file, " by copying source reg %d:%s to temporary reg %d\n",
	       REGNO (src), GET_MODE_NAME (GET_MODE (src)), REGNO (dest));
    }
  emit_insn_before (gen_move_insn (dest, src), cand->insn);
}

/* Check whether any inputs to candidate CAND_INDEX's instruction could
   change at rematerialization points and replace them with new pseudo
   registers if so.  */

void
early_remat::stabilize_pattern (unsigned int cand_index)
{
  remat_candidate *cand = &m_candidates[cand_index];
  if (cand->stabilized_p)
    return;

  remat_equiv_class *ec = cand->equiv_class;
  gcc_checking_assert (!ec || cand_index == ec->representative);

  /* Record the replacements we've made so far, so that we don't
     create two separate registers for match_dups.  Lookup is O(n),
     but the n is very small.  */
  typedef std::pair<rtx, rtx> reg_pair;
  auto_vec<reg_pair, 16> reg_map;

  rtx_insn *insn = cand->insn;
  df_ref ref;
  FOR_EACH_INSN_USE (ref, insn)
    {
      unsigned int old_regno = DF_REF_REGNO (ref);
      rtx *loc = DF_REF_REAL_LOC (ref);

      if (HARD_REGISTER_NUM_P (old_regno) && fixed_regs[old_regno])
	{
	  /* We checked when adding the candidate that the value is stable.  */
	  gcc_checking_assert (!rtx_unstable_p (*loc));
	  continue;
	}

      if (bitmap_bit_p (&m_candidate_regnos, old_regno))
	/* We already know which candidate provides the definition
	   and will handle it during copying.  */
	continue;

      if (stable_use_p (old_regno))
	/* We can continue to use the existing register.  */
	continue;

      /* We need to replace the register.  See whether we've already
	 created a suitable copy.  */
      rtx old_reg = *loc;
      rtx new_reg = NULL_RTX;
      machine_mode mode = GET_MODE (old_reg);
      reg_pair *p;
      unsigned int pi;
      FOR_EACH_VEC_ELT (reg_map, pi, p)
	if (REGNO (p->first) == old_regno
	    && GET_MODE (p->first) == mode)
	  {
	    new_reg = p->second;
	    break;
	  }

      if (!new_reg)
	{
	  /* Create a new register and initialize it just before
	     the instruction.  */
	  new_reg = gen_reg_rtx (mode);
	  reg_map.safe_push (reg_pair (old_reg, new_reg));
	  if (ec)
	    {
	      unsigned int member_index;
	      bitmap_iterator bi;
	      EXECUTE_IF_SET_IN_BITMAP (ec->members, 0, member_index, bi)
		emit_copy_before (member_index, new_reg, old_reg);
	    }
	  else
	    emit_copy_before (cand_index, new_reg, old_reg);
	}
      validate_change (insn, loc, new_reg, true);
    }
  if (num_changes_pending ())
    {
      if (!apply_change_group ())
	/* We checked when adding the candidates that the pattern allows
	   hard registers to be replaced.  Nothing else should make the
	   changes invalid.  */
	gcc_unreachable ();

      if (ec)
	{
	  /* Copy the new pattern to other members of the equivalence
	     class.  */
	  unsigned int member_index;
	  bitmap_iterator bi;
	  EXECUTE_IF_SET_IN_BITMAP (ec->members, 0, member_index, bi)
	    if (cand_index != member_index)
	      {
		rtx_insn *other_insn = m_candidates[member_index].insn;
		if (!validate_change (other_insn, &PATTERN (other_insn),
				      copy_insn (PATTERN (insn)), 0))
		  /* If the original instruction was valid then the copy
		     should be too.  */
		  gcc_unreachable ();
	      }
	}
    }

  cand->stabilized_p = true;
}

/* Change CAND's instruction so that it sets CAND->copy_regno instead
   of CAND->regno.  */

void
early_remat::replace_dest_with_copy (unsigned int cand_index)
{
  remat_candidate *cand = &m_candidates[cand_index];
  df_ref def;
  FOR_EACH_INSN_DEF (def, cand->insn)
    if (DF_REF_REGNO (def) == cand->regno)
      validate_change (cand->insn, DF_REF_REAL_LOC (def),
		       regno_reg_rtx[cand->copy_regno], 1);
}

/* Make sure that the candidates used by candidate CAND_INDEX are available.
   There are two ways of doing this for an input candidate I:

   (1) Using the existing register number and ensuring that I is available.

   (2) Using a new register number (recorded in copy_regno) and adding I
       to VIA_COPY.  This guarantees that making I available does not
       conflict with other uses of the original register.

   REQUIRED is the set of candidates that are required but not available
   before the copy of CAND_INDEX.  AVAILABLE is the set of candidates
   that are already available before the copy of CAND_INDEX.  REACHING
   is the set of candidates that reach the copy of CAND_INDEX.  VIA_COPY
   is the set of candidates that will use new register numbers recorded
   in copy_regno instead of the original ones.  */

void
early_remat::stabilize_candidate_uses (unsigned int cand_index,
				       bitmap required, bitmap available,
				       bitmap reaching, bitmap via_copy)
{
  remat_candidate *cand = &m_candidates[cand_index];
  df_ref use;
  FOR_EACH_INSN_USE (use, cand->insn)
    {
      unsigned int regno = DF_REF_REGNO (use);
      if (!bitmap_bit_p (&m_candidate_regnos, regno))
	continue;

      /* Work out which candidate provides the definition.  */
      bitmap defs = m_regno_to_candidates[regno];
      bitmap_and (&m_tmp_bitmap, cand->uses, defs);
      gcc_checking_assert (bitmap_single_bit_set_p (&m_tmp_bitmap));
      unsigned int def_index = bitmap_first_set_bit (&m_tmp_bitmap);

      /* First see if DEF_INDEX is the only reaching definition of REGNO
	 at this point too and if it is or will become available.  We can
	 continue to use REGNO if so.  */
      bitmap_and (&m_tmp_bitmap, reaching, defs);
      if (bitmap_single_bit_set_p (&m_tmp_bitmap)
	  && bitmap_first_set_bit (&m_tmp_bitmap) == def_index
	  && ((available && bitmap_bit_p (available, def_index))
	      || bitmap_bit_p (required, def_index)))
	{
	  if (dump_file)
	    fprintf (dump_file, ";; Keeping reg %d for use of candidate %d"
		     " in candidate %d\n", regno, def_index, cand_index);
	  continue;
	}

      /* Otherwise fall back to using a copy.  There are other cases
	 in which we *could* continue to use REGNO, but there's not
	 really much point.  Using a separate register ought to make
	 things easier for the register allocator.  */
      remat_candidate *def_cand = &m_candidates[def_index];
      rtx *loc = DF_REF_REAL_LOC (use);
      rtx new_reg;
      if (bitmap_set_bit (via_copy, def_index))
	{
	  new_reg = gen_reg_rtx (GET_MODE (*loc));
	  def_cand->copy_regno = REGNO (new_reg);
	  if (dump_file)
	    fprintf (dump_file, ";; Creating reg %d for use of candidate %d"
		     " in candidate %d\n", REGNO (new_reg), def_index,
		     cand_index);
	}
      else
	new_reg = regno_reg_rtx[def_cand->copy_regno];
      validate_change (cand->insn, loc, new_reg, 1);
    }
}

/* Rematerialize the candidates in REQUIRED after instruction INSN,
   given that the candidates in AVAILABLE are already available
   and that REACHING is the set of candidates live after INSN.
   REQUIRED and AVAILABLE are disjoint on entry.

   Clear REQUIRED on exit.  */

void
early_remat::emit_remat_insns (bitmap required, bitmap available,
			       bitmap reaching, rtx_insn *insn)
{
  /* Quick exit if there's nothing to do.  */
  if (empty_p (required))
    return;

  /* Only reaching definitions should be available or required.  */
  gcc_checking_assert (!bitmap_intersect_compl_p (required, reaching));
  if (available)
    gcc_checking_assert (!bitmap_intersect_compl_p (available, reaching));

  bitmap_head via_copy;
  bitmap_initialize (&via_copy, &m_obstack);
  while (!bitmap_empty_p (required) || !bitmap_empty_p (&via_copy))
    {
      /* Pick the lowest-indexed candidate left.  */
      unsigned int required_index = (bitmap_empty_p (required)
				     ? ~0U : bitmap_first_set_bit (required));
      unsigned int via_copy_index = (bitmap_empty_p (&via_copy)
				     ? ~0U : bitmap_first_set_bit (&via_copy));
      unsigned int cand_index = MIN (required_index, via_copy_index);
      remat_candidate *cand = &m_candidates[cand_index];

      bool via_copy_p = (cand_index == via_copy_index);
      if (via_copy_p)
	bitmap_clear_bit (&via_copy, cand_index);
      else
	{
	  /* Remove all candidates for the same register from REQUIRED.  */
	  bitmap_and (&m_tmp_bitmap, reaching,
		      m_regno_to_candidates[cand->regno]);
	  bitmap_and_compl_into (required, &m_tmp_bitmap);
	  gcc_checking_assert (!bitmap_bit_p (required, cand_index));

	  /* Only rematerialize if we have a single reaching definition
	     of the register.  */
	  if (!bitmap_single_bit_set_p (&m_tmp_bitmap))
	    {
	      if (dump_file)
		{
		  fprintf (dump_file, ";; Can't rematerialize reg %d after ",
			   cand->regno);
		  dump_insn_id (insn);
		  fprintf (dump_file, ": more than one reaching definition\n");
		}
	      continue;
	    }

	  /* Skip candidates that can't be rematerialized.  */
	  if (!cand->can_copy_p)
	    continue;

	  /* Check the function precondition.  */
	  gcc_checking_assert (!available
			       || !bitmap_bit_p (available, cand_index));
	}

      /* Invalid candidates should have been weeded out by now.  */
      gcc_assert (cand->can_copy_p);

      rtx new_pattern;
      if (cand->constant_p)
	{
	  /* Emit a simple move.  */
	  unsigned int regno = via_copy_p ? cand->copy_regno : cand->regno;
	  new_pattern = gen_move_insn (regno_reg_rtx[regno], cand->remat_rtx);
	}
      else
	{
	  /* If this is the first time we've copied the instruction, make
	     sure that any inputs will have the same value after INSN.  */
	  stabilize_pattern (cand_index);

	  /* Temporarily adjust the original instruction so that it has
	     the right form for the copy.  */
	  if (via_copy_p)
	    replace_dest_with_copy (cand_index);
	  if (cand->uses)
	    stabilize_candidate_uses (cand_index, required, available,
				      reaching, &via_copy);

	  /* Get the new instruction pattern.  */
	  new_pattern = copy_insn (cand->remat_rtx);

	  /* Undo the temporary changes.  */
	  cancel_changes (0);
	}

      /* Emit the new instruction.  */
      rtx_insn *new_insn = emit_insn_after (new_pattern, insn);

      if (dump_file)
	{
	  fprintf (dump_file, ";; Rematerializing candidate %d after ",
		   cand_index);
	  dump_insn_id (insn);
	  if (via_copy_p)
	    fprintf (dump_file, " with new destination reg %d",
		     cand->copy_regno);
	  fprintf (dump_file, ":\n\n");
	  print_rtl_single (dump_file, new_insn);
	  fprintf (dump_file, "\n");
	}
    }
}

/* Recompute INFO's available_out set, given that it's distinct from
   available_in and available_locally.  */

bool
early_remat::set_available_out (remat_block_info *info)
{
  if (empty_p (info->available_locally))
    return bitmap_and_compl (get_bitmap (&info->available_out),
			     info->available_in, info->rd_kill);

  if (empty_p (info->rd_kill))
    return bitmap_ior (get_bitmap (&info->available_out),
		       info->available_locally, info->available_in);

  return bitmap_ior_and_compl (get_bitmap (&info->available_out),
			       info->available_locally, info->available_in,
			       info->rd_kill);
}

/* If BB has more than one call, decide which candidates should be
   rematerialized after the non-final calls and emit the associated
   instructions.  Record other information about the block in preparation
   for the global phase.  */

void
early_remat::process_block (basic_block bb)
{
  remat_block_info *info = &m_block_info[bb->index];
  rtx_insn *last_call = NULL;
  rtx_insn *insn;

  /* Ensure that we always use the same candidate index to refer to an
     equivalence class.  */
  if (info->rd_out == info->rd_in)
    {
      canon_bitmap (&info->rd_in);
      info->rd_out = info->rd_in;
    }
  else
    {
      canon_bitmap (&info->rd_in);
      canon_bitmap (&info->rd_out);
    }
  canon_bitmap (&info->rd_kill);
  canon_bitmap (&info->rd_gen);

  /* The set of candidates that should be rematerialized on entry to the
     block or after the previous call (whichever is more recent).  */
  init_temp_bitmap (&m_required);

  /* The set of candidates that reach the current instruction (i.e. are
     live just before the instruction).  */
  bitmap_head reaching;
  bitmap_initialize (&reaching, &m_obstack);
  if (info->rd_in)
    bitmap_copy (&reaching, info->rd_in);

  /* The set of candidates that are live and available without
     rematerialization just before the current instruction.  This only
     accounts for earlier candidates in the block, or those that become
     available by being added to M_REQUIRED.  */
  init_temp_bitmap (&m_available);

  /* Get the range of candidates in the block.  */
  unsigned int next_candidate = info->first_candidate;
  unsigned int num_candidates = info->num_candidates;
  remat_candidate *next_def = (num_candidates > 0
			       ? &m_candidates[next_candidate]
			       : NULL);

  FOR_BB_INSNS (bb, insn)
    {
      if (!NONDEBUG_INSN_P (insn))
	continue;

      /* First process uses, since this is a forward walk.  */
      df_ref ref;
      FOR_EACH_INSN_USE (ref, insn)
	{
	  unsigned int regno = DF_REF_REGNO (ref);
	  if (bitmap_bit_p (&m_candidate_regnos, regno))
	    {
	      bitmap defs = m_regno_to_candidates[regno];
	      bitmap_and (&m_tmp_bitmap, defs, &reaching);
	      gcc_checking_assert (!bitmap_empty_p (&m_tmp_bitmap));
	      if (!bitmap_intersect_p (defs, m_available))
		{
		  /* There has been no definition of the register since
		     the last call or the start of the block (whichever
		     is most recent).  Mark the reaching definitions
		     as required at that point and thus available here.  */
		  bitmap_ior_into (m_required, &m_tmp_bitmap);
		  bitmap_ior_into (m_available, &m_tmp_bitmap);
		}
	    }
	}

      if (CALL_P (insn))
	{
	  if (!last_call)
	    {
	      /* The first call in the block.  Record which candidates are
		 required at the start of the block.  */
	      copy_temp_bitmap (&info->required_in, &m_required);
	      init_temp_bitmap (&m_required);
	    }
	  else
	    {
	      /* The fully-local case: candidates that need to be
		 rematerialized after a previous call in the block.  */
	      restrict_remat_for_call (m_required, last_call);
	      emit_remat_insns (m_required, NULL, info->rd_after_call,
				last_call);
	    }
	  last_call = insn;
	  bitmap_clear (m_available);
	  gcc_checking_assert (empty_p (m_required));
	}

      /* Now process definitions.  */
      while (next_def && insn == next_def->insn)
	{
	  unsigned int gen = canon_candidate (next_candidate);

	  /* Other candidates with the same regno are not available
	     any more.  */
	  bitmap kill = m_regno_to_candidates[next_def->regno];
	  bitmap_and_compl_into (m_available, kill);
	  bitmap_and_compl_into (&reaching, kill);

	  /* Record that this candidate is available without
	     rematerialization.  */
	  bitmap_set_bit (m_available, gen);
	  bitmap_set_bit (&reaching, gen);

	  /* Find the next candidate in the block.  */
	  num_candidates -= 1;
	  next_candidate -= 1;
	  if (num_candidates > 0)
	    next_def -= 1;
	  else
	    next_def = NULL;
	}

      if (insn == last_call)
	bitmap_copy (get_bitmap (&info->rd_after_call), &reaching);
    }
  bitmap_clear (&reaching);
  gcc_checking_assert (num_candidates == 0);

  /* Remove values from the available set if they aren't live (and so
     aren't interesting to successor blocks).  */
  if (info->rd_out)
    bitmap_and_into (m_available, info->rd_out);

  /* Record the accumulated information.  */
  info->last_call = last_call;
  info->abnormal_call_p = (last_call
			   && last_call == BB_END (bb)
			   && has_abnormal_or_eh_outgoing_edge_p (bb));
  copy_temp_bitmap (&info->available_locally, &m_available);
  if (last_call)
    copy_temp_bitmap (&info->required_after_call, &m_required);
  else
    copy_temp_bitmap (&info->required_in, &m_required);

  /* Assume at first that all live-in values are available without
     rematerialization (i.e. start with the most optimistic assumption).  */
  if (info->available_in)
    {
      if (info->rd_in)
	bitmap_copy (info->available_in, info->rd_in);
      else
	BITMAP_FREE (info->available_in);
    }

  if (last_call || empty_p (info->available_in))
    /* The values available on exit from the block are exactly those that
       are available locally.  This set doesn't change.  */
    info->available_out = info->available_locally;
  else if (empty_p (info->available_locally) && empty_p (info->rd_kill))
    /* The values available on exit are the same as those available on entry.
       Updating one updates the other.  */
    info->available_out = info->available_in;
  else
    set_available_out (info);
}

/* Process each block as for process_block, visiting dominators before
   the blocks they dominate.  */

void
early_remat::local_phase (void)
{
  if (dump_file)
    fprintf (dump_file, "\n;; Local phase:\n");

  int *postorder = df_get_postorder (DF_BACKWARD);
  unsigned int postorder_len = df_get_n_blocks (DF_BACKWARD);
  for (unsigned int i = postorder_len; i-- > 0; )
    if (postorder[i] >= NUM_FIXED_BLOCKS)
      process_block (BASIC_BLOCK_FOR_FN (m_fn, postorder[i]));
}

/* Return true if available values survive across edge E.  */

static inline bool
available_across_edge_p (edge e)
{
  return (e->flags & EDGE_EH) == 0;
}

/* Propagate information from the available_out set of E->src to the
   available_in set of E->dest, when computing global availability.
   Return true if something changed.  */

bool
early_remat::avail_confluence_n (edge e)
{
  remat_block_info *src = &er->m_block_info[e->src->index];
  remat_block_info *dest = &er->m_block_info[e->dest->index];

  if (!available_across_edge_p (e))
    return false;

  if (empty_p (dest->available_in))
    return false;

  if (!src->available_out)
    {
      bitmap_clear (dest->available_in);
      return true;
    }

  return bitmap_and_into (dest->available_in, src->available_out);
}

/* Propagate information from the available_in set of block BB_INDEX
   to available_out.  Return true if something changed.  */

bool
early_remat::avail_transfer (int bb_index)
{
  remat_block_info *info = &er->m_block_info[bb_index];

  if (info->available_out == info->available_locally)
    return false;

  if (info->available_out == info->available_in)
    /* Assume that we are only called if the input changed.  */
    return true;

  return er->set_available_out (info);
}

/* Compute global availability for the function, starting with the local
   information computed by local_phase.  */

void
early_remat::compute_availability (void)
{
  /* We use df_simple_dataflow instead of the lcm routines for three reasons:

     (1) it avoids recomputing the traversal order;
     (2) many of the sets are likely to be sparse, so we don't necessarily
	 want to use sbitmaps; and
     (3) it means we can avoid creating an explicit kill set for the call.  */
  er = this;
  bitmap_clear (&m_tmp_bitmap);
  bitmap_set_range (&m_tmp_bitmap, 0, last_basic_block_for_fn (m_fn));
  df_simple_dataflow (DF_FORWARD, NULL, NULL,
		      avail_confluence_n, avail_transfer,
		      &m_tmp_bitmap, df_get_postorder (DF_FORWARD),
		      df_get_n_blocks (DF_FORWARD));
  er = 0;

  /* Restrict the required_in sets to values that aren't available.  */
  basic_block bb;
  FOR_EACH_BB_FN (bb, m_fn)
    {
      remat_block_info *info = &m_block_info[bb->index];
      if (info->required_in && info->available_in)
	bitmap_and_compl_into (info->required_in, info->available_in);
    }
}

/* Make sure that INFO's available_out and available_in sets are unique.  */

inline void
early_remat::unshare_available_sets (remat_block_info *info)
{
  if (info->available_in && info->available_in == info->available_out)
    {
      info->available_in = alloc_bitmap ();
      bitmap_copy (info->available_in, info->available_out);
    }
}

/* Return true if it is possible to move rematerializations from the
   destination of E to the source of E.  */

inline bool
early_remat::can_move_across_edge_p (edge e)
{
  return (available_across_edge_p (e)
	  && !m_block_info[e->src->index].abnormal_call_p);
}

/* Return true if it is cheaper to rematerialize values at the head of
   block QUERY_BB_INDEX instead of rematerializing in its predecessors.  */

bool
early_remat::local_remat_cheaper_p (unsigned int query_bb_index)
{
  if (m_block_info[query_bb_index].remat_frequency_valid_p)
    return m_block_info[query_bb_index].local_remat_cheaper_p;

  /* Iteratively compute the cost of rematerializing values in the
     predecessor blocks, then compare that with the cost of
     rematerializing at the head of the block.

     A cycle indicates that there is no call on that execution path,
     so it isn't necessary to rematerialize on that path.  */
  auto_vec<basic_block, 16> stack;
  stack.quick_push (BASIC_BLOCK_FOR_FN (m_fn, query_bb_index));
  while (!stack.is_empty ())
    {
      basic_block bb = stack.last ();
      remat_block_info *info = &m_block_info[bb->index];
      if (info->remat_frequency_valid_p)
	{
	  stack.pop ();
	  continue;
	}

      info->visited_p = true;
      int frequency = 0;
      bool can_move_p = true;
      edge e;
      edge_iterator ei;
      FOR_EACH_EDGE (e, ei, bb->preds)
	if (!can_move_across_edge_p (e))
	  {
	    can_move_p = false;
	    break;
	  }
	else if (m_block_info[e->src->index].last_call)
	  /* We'll rematerialize after the call.  */
	  frequency += e->src->count.to_frequency (m_fn);
	else if (m_block_info[e->src->index].remat_frequency_valid_p)
	  /* Add the cost of rematerializing at the head of E->src
	     or in its predecessors (whichever is cheaper).  */
	  frequency += m_block_info[e->src->index].remat_frequency;
	else if (!m_block_info[e->src->index].visited_p)
	  /* Queue E->src and then revisit this block again.  */
	  stack.safe_push (e->src);

      /* Come back to this block later if we need to process some of
	 its predecessors.  */
      if (stack.last () != bb)
	continue;

      /* If rematerializing in and before the block have equal cost, prefer
	 rematerializing in the block.  This should shorten the live range.  */
      int bb_frequency = bb->count.to_frequency (m_fn);
      if (!can_move_p || frequency >= bb_frequency)
	{
	  info->local_remat_cheaper_p = true;
	  info->remat_frequency = bb_frequency;
	}
      else
	info->remat_frequency = frequency;
      info->remat_frequency_valid_p = true;
      info->visited_p = false;
      if (dump_file)
	{
	  if (!can_move_p)
	    fprintf (dump_file, ";; Need to rematerialize at the head of"
		     " block %d; cannot move to predecessors.\n", bb->index);
	  else
	    {
	      fprintf (dump_file, ";; Block %d has frequency %d,"
		       " rematerializing in predecessors has frequency %d",
		       bb->index, bb_frequency, frequency);
	      if (info->local_remat_cheaper_p)
		fprintf (dump_file, "; prefer to rematerialize"
			 " in the block\n");
	      else
		fprintf (dump_file, "; prefer to rematerialize"
			 " in predecessors\n");
	    }
	}
      stack.pop ();
    }
  return m_block_info[query_bb_index].local_remat_cheaper_p;
}

/* Return true if we cannot rematerialize candidate CAND_INDEX at the head of
   block BB_INDEX.  */

bool
early_remat::need_to_move_candidate_p (unsigned int bb_index,
				       unsigned int cand_index)
{
  remat_block_info *info = &m_block_info[bb_index];
  remat_candidate *cand = &m_candidates[cand_index];
  basic_block bb = BASIC_BLOCK_FOR_FN (m_fn, bb_index);

  /* If there is more than one reaching definition of REGNO,
     we'll need to rematerialize in predecessors instead.  */
  bitmap_and (&m_tmp_bitmap, info->rd_in, m_regno_to_candidates[cand->regno]);
  if (!bitmap_single_bit_set_p (&m_tmp_bitmap))
    {
      if (dump_file)
	fprintf (dump_file, ";; Cannot rematerialize %d at the"
		 " head of block %d because there is more than one"
		 " reaching definition of reg %d\n", cand_index,
		 bb_index, cand->regno);
      return true;
    }

  /* Likewise if rematerializing CAND here would clobber a live register.  */
  if (cand->clobbers
      && bitmap_intersect_p (cand->clobbers, DF_LR_IN (bb)))
    {
      if (dump_file)
	fprintf (dump_file, ";; Cannot rematerialize %d at the"
		 " head of block %d because it would clobber live"
		 " registers\n", cand_index, bb_index);
      return true;
    }

  return false;
}

/* Set REQUIRED to the minimum set of candidates that must be rematerialized
   in predecessors of block BB_INDEX instead of at the start of the block.  */

void
early_remat::compute_minimum_move_set (unsigned int bb_index,
				       bitmap required)
{
  remat_block_info *info = &m_block_info[bb_index];
  bitmap_head remaining;

  bitmap_clear (required);
  bitmap_initialize (&remaining, &m_obstack);
  bitmap_copy (&remaining, info->required_in);
  while (!bitmap_empty_p (&remaining))
    {
      unsigned int cand_index = bitmap_first_set_bit (&remaining);
      remat_candidate *cand = &m_candidates[cand_index];
      bitmap_clear_bit (&remaining, cand_index);

      /* Leave invalid candidates where they are.  */
      if (!cand->can_copy_p)
	continue;

      /* Decide whether to move this candidate.  */
      if (!bitmap_bit_p (required, cand_index))
	{
	  if (!need_to_move_candidate_p (bb_index, cand_index))
	    continue;
	  bitmap_set_bit (required, cand_index);
	}

      /* Also move values used by the candidate, so that we don't
	 rematerialize them twice.  */
      if (cand->uses)
	{
	  bitmap_ior_and_into (required, cand->uses, info->required_in);
	  bitmap_ior_and_into (&remaining, cand->uses, info->required_in);
	}
    }
}

/* Make the predecessors of BB_INDEX rematerialize the candidates in
   REQUIRED.  Add any blocks whose required_in set changes to
   PENDING_BLOCKS.  */

void
early_remat::move_to_predecessors (unsigned int bb_index, bitmap required,
				   bitmap pending_blocks)
{
  if (empty_p (required))
    return;
  remat_block_info *dest_info = &m_block_info[bb_index];
  basic_block bb = BASIC_BLOCK_FOR_FN (m_fn, bb_index);
  edge e;
  edge_iterator ei;
  FOR_EACH_EDGE (e, ei, bb->preds)
    {
      remat_block_info *src_info = &m_block_info[e->src->index];

      /* Restrict the set we add to the reaching definitions.  */
      bitmap_and (&m_tmp_bitmap, required, src_info->rd_out);
      if (bitmap_empty_p (&m_tmp_bitmap))
	continue;

      if (!can_move_across_edge_p (e))
	{
	  /* We can't move the rematerialization and we can't do it at
	     the start of the block either.  In this case we just give up
	     and rely on spilling to make the values available across E.  */
	  if (dump_file)
	    {
	      fprintf (dump_file, ";; Cannot rematerialize the following"
		       " candidates in block %d:", e->src->index);
	      dump_candidate_bitmap (required);
	      fprintf (dump_file, "\n");
	    }
	  continue;
	}

      /* Remove candidates that are already available.  */
      if (src_info->available_out)
	{
	  bitmap_and_compl_into (&m_tmp_bitmap, src_info->available_out);
	  if (bitmap_empty_p (&m_tmp_bitmap))
	    continue;
	}

      /* Add the remaining candidates to the appropriate required set.  */
      if (dump_file)
	{
	  fprintf (dump_file, ";; Moving this set from block %d"
		   " to block %d:", bb_index, e->src->index);
	  dump_candidate_bitmap (&m_tmp_bitmap);
	  fprintf (dump_file, "\n");
	}
      /* If the source block contains a call, we want to rematerialize
	 after the call, otherwise we want to rematerialize at the start
	 of the block.  */
      bitmap src_required = get_bitmap (src_info->last_call
					? &src_info->required_after_call
					: &src_info->required_in);
      if (bitmap_ior_into (src_required, &m_tmp_bitmap))
	{
	  if (!src_info->last_call)
	    bitmap_set_bit (pending_blocks, e->src->index);
	  unshare_available_sets (src_info);
	  bitmap_ior_into (get_bitmap (&src_info->available_out),
			   &m_tmp_bitmap);
	}
    }

  /* The candidates are now available on entry to the block.  */
  bitmap_and_compl_into (dest_info->required_in, required);
  unshare_available_sets (dest_info);
  bitmap_ior_into (get_bitmap (&dest_info->available_in), required);
}

/* Go through the candidates that are currently marked as being
   rematerialized at the beginning of a block.  Decide in each case
   whether that's valid and profitable; if it isn't, move the
   rematerialization to predecessor blocks instead.  */

void
early_remat::choose_rematerialization_points (void)
{
  bitmap_head required;
  bitmap_head pending_blocks;

  int *postorder = df_get_postorder (DF_BACKWARD);
  unsigned int postorder_len = df_get_n_blocks (DF_BACKWARD);
  bitmap_initialize (&required, &m_obstack);
  bitmap_initialize (&pending_blocks, &m_obstack);
  do
    /* Process the blocks in postorder, to reduce the number of iterations
       of the outer loop.  */
    for (unsigned int i = 0; i < postorder_len; ++i)
      {
	unsigned int bb_index = postorder[i];
	remat_block_info *info = &m_block_info[bb_index];
	bitmap_clear_bit (&pending_blocks, bb_index);

	if (empty_p (info->required_in))
	  continue;

	if (info->available_in)
	  gcc_checking_assert (!bitmap_intersect_p (info->required_in,
						    info->available_in));

	if (local_remat_cheaper_p (bb_index))
	  {
	    /* We'd prefer to rematerialize at the head of the block.
	       Only move candidates if we need to.  */
	    compute_minimum_move_set (bb_index, &required);
	    move_to_predecessors (bb_index, &required, &pending_blocks);
	  }
	else
	  move_to_predecessors (bb_index, info->required_in,
				&pending_blocks);
      }
  while (!bitmap_empty_p (&pending_blocks));
  bitmap_clear (&required);
}

/* Emit all rematerialization instructions queued for BB.  */

void
early_remat::emit_remat_insns_for_block (basic_block bb)
{
  remat_block_info *info = &m_block_info[bb->index];

  if (info->last_call && !empty_p (info->required_after_call))
    {
      restrict_remat_for_call (info->required_after_call, info->last_call);
      emit_remat_insns (info->required_after_call, NULL,
			info->rd_after_call, info->last_call);
    }

  if (!empty_p (info->required_in))
    {
      rtx_insn *insn = BB_HEAD (bb);
      while (insn != BB_END (bb)
	     && !INSN_P (NEXT_INSN (insn)))
	insn = NEXT_INSN (insn);
      restrict_remat_for_unavail_regs (info->required_in, DF_LR_IN (bb));
      emit_remat_insns (info->required_in, info->available_in,
			info->rd_in, insn);
    }
}

/* Decide which candidates in each block's REQUIRED_IN set need to be
   rematerialized and decide where the rematerialization instructions
   should go.  Emit queued rematerialization instructions at the start
   of blocks and after the last calls in blocks.  */

void
early_remat::global_phase (void)
{
  compute_availability ();
  if (dump_file)
    {
      fprintf (dump_file, "\n;; Blocks after computing global"
	       " availability:\n");
      dump_all_blocks ();
    }

  choose_rematerialization_points ();
  if (dump_file)
    {
      fprintf (dump_file, "\n;; Blocks after choosing rematerialization"
	       " points:\n");
      dump_all_blocks ();
    }

  basic_block bb;
  FOR_EACH_BB_FN (bb, m_fn)
    emit_remat_insns_for_block (bb);
}

/* Main function for the pass.  */

void
early_remat::run (void)
{
  df_analyze ();

  if (!collect_candidates ())
    return;

  init_block_info ();
  sort_candidates ();
  finalize_candidate_indices ();
  if (dump_file)
    dump_all_candidates ();

  compute_rd ();
  decide_candidate_validity ();
  local_phase ();
  global_phase ();
}

early_remat::early_remat (function *fn, sbitmap selected_modes)
  : m_fn (fn),
    m_selected_modes (selected_modes),
    m_available (0),
    m_required (0),
    m_value_table (63)
{
  bitmap_obstack_initialize (&m_obstack);
  bitmap_initialize (&m_candidate_regnos, &m_obstack);
  bitmap_initialize (&m_tmp_bitmap, &m_obstack);
}

early_remat::~early_remat ()
{
  bitmap_obstack_release (&m_obstack);
}

namespace {

const pass_data pass_data_early_remat =
{
  RTL_PASS, /* type */
  "early_remat", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_EARLY_REMAT, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  TODO_df_finish, /* todo_flags_finish */
};

class pass_early_remat : public rtl_opt_pass
{
public:
  pass_early_remat (gcc::context *ctxt)
    : rtl_opt_pass (pass_data_early_remat, ctxt)
  {}

  /* opt_pass methods: */
  virtual bool gate (function *)
  {
    return optimize > 1 && NUM_POLY_INT_COEFFS > 1;
  }

  virtual unsigned int execute (function *f)
  {
    auto_sbitmap selected_modes (NUM_MACHINE_MODES);
    bitmap_clear (selected_modes);
    targetm.select_early_remat_modes (selected_modes);
    if (!bitmap_empty_p (selected_modes))
      early_remat (f, selected_modes).run ();
    return 0;
  }
}; // class pass_early_remat

} // anon namespace

rtl_opt_pass *
make_pass_early_remat (gcc::context *ctxt)
{
  return new pass_early_remat (ctxt);
}
