/* Common subexpression elimination library for GNU compiler.
   Copyright (C) 1987-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 "target.h"
#include "rtl.h"
#include "tree.h"
#include "df.h"
#include "memmodel.h"
#include "tm_p.h"
#include "regs.h"
#include "emit-rtl.h"
#include "dumpfile.h"
#include "cselib.h"
#include "params.h"

/* A list of cselib_val structures.  */
struct elt_list
{
  struct elt_list *next;
  cselib_val *elt;
};

static bool cselib_record_memory;
static bool cselib_preserve_constants;
static bool cselib_any_perm_equivs;
static inline void promote_debug_loc (struct elt_loc_list *l);
static struct elt_list *new_elt_list (struct elt_list *, cselib_val *);
static void new_elt_loc_list (cselib_val *, rtx);
static void unchain_one_value (cselib_val *);
static void unchain_one_elt_list (struct elt_list **);
static void unchain_one_elt_loc_list (struct elt_loc_list **);
static void remove_useless_values (void);
static unsigned int cselib_hash_rtx (rtx, int, machine_mode);
static cselib_val *new_cselib_val (unsigned int, machine_mode, rtx);
static void add_mem_for_addr (cselib_val *, cselib_val *, rtx);
static cselib_val *cselib_lookup_mem (rtx, int);
static void cselib_invalidate_regno (unsigned int, machine_mode);
static void cselib_invalidate_mem (rtx);
static void cselib_record_set (rtx, cselib_val *, cselib_val *);
static void cselib_record_sets (rtx_insn *);

struct expand_value_data
{
  bitmap regs_active;
  cselib_expand_callback callback;
  void *callback_arg;
  bool dummy;
};

static rtx cselib_expand_value_rtx_1 (rtx, struct expand_value_data *, int);

/* There are three ways in which cselib can look up an rtx:
   - for a REG, the reg_values table (which is indexed by regno) is used
   - for a MEM, we recursively look up its address and then follow the
     addr_list of that value
   - for everything else, we compute a hash value and go through the hash
     table.  Since different rtx's can still have the same hash value,
     this involves walking the table entries for a given value and comparing
     the locations of the entries with the rtx we are looking up.  */

struct cselib_hasher : nofree_ptr_hash <cselib_val>
{
  struct key {
    /* The rtx value and its mode (needed separately for constant
       integers).  */
    machine_mode mode;
    rtx x;
    /* The mode of the contaning MEM, if any, otherwise VOIDmode.  */
    machine_mode memmode;
  };
  typedef key *compare_type;
  static inline hashval_t hash (const cselib_val *);
  static inline bool equal (const cselib_val *, const key *);
};

/* The hash function for our hash table.  The value is always computed with
   cselib_hash_rtx when adding an element; this function just extracts the
   hash value from a cselib_val structure.  */

inline hashval_t
cselib_hasher::hash (const cselib_val *v)
{
  return v->hash;
}

/* The equality test for our hash table.  The first argument V is a table
   element (i.e. a cselib_val), while the second arg X is an rtx.  We know
   that all callers of htab_find_slot_with_hash will wrap CONST_INTs into a
   CONST of an appropriate mode.  */

inline bool
cselib_hasher::equal (const cselib_val *v, const key *x_arg)
{
  struct elt_loc_list *l;
  rtx x = x_arg->x;
  machine_mode mode = x_arg->mode;
  machine_mode memmode = x_arg->memmode;

  if (mode != GET_MODE (v->val_rtx))
    return false;

  if (GET_CODE (x) == VALUE)
    return x == v->val_rtx;

  /* We don't guarantee that distinct rtx's have different hash values,
     so we need to do a comparison.  */
  for (l = v->locs; l; l = l->next)
    if (rtx_equal_for_cselib_1 (l->loc, x, memmode, 0))
      {
	promote_debug_loc (l);
	return true;
      }

  return false;
}

/* A table that enables us to look up elts by their value.  */
static hash_table<cselib_hasher> *cselib_hash_table;

/* A table to hold preserved values.  */
static hash_table<cselib_hasher> *cselib_preserved_hash_table;

/* This is a global so we don't have to pass this through every function.
   It is used in new_elt_loc_list to set SETTING_INSN.  */
static rtx_insn *cselib_current_insn;

/* The unique id that the next create value will take.  */
static unsigned int next_uid;

/* The number of registers we had when the varrays were last resized.  */
static unsigned int cselib_nregs;

/* Count values without known locations, or with only locations that
   wouldn't have been known except for debug insns.  Whenever this
   grows too big, we remove these useless values from the table.

   Counting values with only debug values is a bit tricky.  We don't
   want to increment n_useless_values when we create a value for a
   debug insn, for this would get n_useless_values out of sync, but we
   want increment it if all locs in the list that were ever referenced
   in nondebug insns are removed from the list.

   In the general case, once we do that, we'd have to stop accepting
   nondebug expressions in the loc list, to avoid having two values
   equivalent that, without debug insns, would have been made into
   separate values.  However, because debug insns never introduce
   equivalences themselves (no assignments), the only means for
   growing loc lists is through nondebug assignments.  If the locs
   also happen to be referenced in debug insns, it will work just fine.

   A consequence of this is that there's at most one debug-only loc in
   each loc list.  If we keep it in the first entry, testing whether
   we have a debug-only loc list takes O(1).

   Furthermore, since any additional entry in a loc list containing a
   debug loc would have to come from an assignment (nondebug) that
   references both the initial debug loc and the newly-equivalent loc,
   the initial debug loc would be promoted to a nondebug loc, and the
   loc list would not contain debug locs any more.

   So the only case we have to be careful with in order to keep
   n_useless_values in sync between debug and nondebug compilations is
   to avoid incrementing n_useless_values when removing the single loc
   from a value that turns out to not appear outside debug values.  We
   increment n_useless_debug_values instead, and leave such values
   alone until, for other reasons, we garbage-collect useless
   values.  */
static int n_useless_values;
static int n_useless_debug_values;

/* Count values whose locs have been taken exclusively from debug
   insns for the entire life of the value.  */
static int n_debug_values;

/* Number of useless values before we remove them from the hash table.  */
#define MAX_USELESS_VALUES 32

/* This table maps from register number to values.  It does not
   contain pointers to cselib_val structures, but rather elt_lists.
   The purpose is to be able to refer to the same register in
   different modes.  The first element of the list defines the mode in
   which the register was set; if the mode is unknown or the value is
   no longer valid in that mode, ELT will be NULL for the first
   element.  */
static struct elt_list **reg_values;
static unsigned int reg_values_size;
#define REG_VALUES(i) reg_values[i]

/* The largest number of hard regs used by any entry added to the
   REG_VALUES table.  Cleared on each cselib_clear_table() invocation.  */
static unsigned int max_value_regs;

/* Here the set of indices I with REG_VALUES(I) != 0 is saved.  This is used
   in cselib_clear_table() for fast emptying.  */
static unsigned int *used_regs;
static unsigned int n_used_regs;

/* We pass this to cselib_invalidate_mem to invalidate all of
   memory for a non-const call instruction.  */
static GTY(()) rtx callmem;

/* Set by discard_useless_locs if it deleted the last location of any
   value.  */
static int values_became_useless;

/* Used as stop element of the containing_mem list so we can check
   presence in the list by checking the next pointer.  */
static cselib_val dummy_val;

/* If non-NULL, value of the eliminated arg_pointer_rtx or frame_pointer_rtx
   that is constant through the whole function and should never be
   eliminated.  */
static cselib_val *cfa_base_preserved_val;
static unsigned int cfa_base_preserved_regno = INVALID_REGNUM;

/* Used to list all values that contain memory reference.
   May or may not contain the useless values - the list is compacted
   each time memory is invalidated.  */
static cselib_val *first_containing_mem = &dummy_val;

static object_allocator<elt_list> elt_list_pool ("elt_list");
static object_allocator<elt_loc_list> elt_loc_list_pool ("elt_loc_list");
static object_allocator<cselib_val> cselib_val_pool ("cselib_val_list");

static pool_allocator value_pool ("value", RTX_CODE_SIZE (VALUE));

/* If nonnull, cselib will call this function before freeing useless
   VALUEs.  A VALUE is deemed useless if its "locs" field is null.  */
void (*cselib_discard_hook) (cselib_val *);

/* If nonnull, cselib will call this function before recording sets or
   even clobbering outputs of INSN.  All the recorded sets will be
   represented in the array sets[n_sets].  new_val_min can be used to
   tell whether values present in sets are introduced by this
   instruction.  */
void (*cselib_record_sets_hook) (rtx_insn *insn, struct cselib_set *sets,
				 int n_sets);

#define PRESERVED_VALUE_P(RTX) \
  (RTL_FLAG_CHECK1 ("PRESERVED_VALUE_P", (RTX), VALUE)->unchanging)

#define SP_BASED_VALUE_P(RTX) \
  (RTL_FLAG_CHECK1 ("SP_BASED_VALUE_P", (RTX), VALUE)->jump)



/* Allocate a struct elt_list and fill in its two elements with the
   arguments.  */

static inline struct elt_list *
new_elt_list (struct elt_list *next, cselib_val *elt)
{
  elt_list *el = elt_list_pool.allocate ();
  el->next = next;
  el->elt = elt;
  return el;
}

/* Allocate a struct elt_loc_list with LOC and prepend it to VAL's loc
   list.  */

static inline void
new_elt_loc_list (cselib_val *val, rtx loc)
{
  struct elt_loc_list *el, *next = val->locs;

  gcc_checking_assert (!next || !next->setting_insn
		       || !DEBUG_INSN_P (next->setting_insn)
		       || cselib_current_insn == next->setting_insn);

  /* If we're creating the first loc in a debug insn context, we've
     just created a debug value.  Count it.  */
  if (!next && cselib_current_insn && DEBUG_INSN_P (cselib_current_insn))
    n_debug_values++;

  val = canonical_cselib_val (val);
  next = val->locs;

  if (GET_CODE (loc) == VALUE)
    {
      loc = canonical_cselib_val (CSELIB_VAL_PTR (loc))->val_rtx;

      gcc_checking_assert (PRESERVED_VALUE_P (loc)
			   == PRESERVED_VALUE_P (val->val_rtx));

      if (val->val_rtx == loc)
	return;
      else if (val->uid > CSELIB_VAL_PTR (loc)->uid)
	{
	  /* Reverse the insertion.  */
	  new_elt_loc_list (CSELIB_VAL_PTR (loc), val->val_rtx);
	  return;
	}

      gcc_checking_assert (val->uid < CSELIB_VAL_PTR (loc)->uid);

      if (CSELIB_VAL_PTR (loc)->locs)
	{
	  /* Bring all locs from LOC to VAL.  */
	  for (el = CSELIB_VAL_PTR (loc)->locs; el->next; el = el->next)
	    {
	      /* Adjust values that have LOC as canonical so that VAL
		 becomes their canonical.  */
	      if (el->loc && GET_CODE (el->loc) == VALUE)
		{
		  gcc_checking_assert (CSELIB_VAL_PTR (el->loc)->locs->loc
				       == loc);
		  CSELIB_VAL_PTR (el->loc)->locs->loc = val->val_rtx;
		}
	    }
	  el->next = val->locs;
	  next = val->locs = CSELIB_VAL_PTR (loc)->locs;
	}

      if (CSELIB_VAL_PTR (loc)->addr_list)
	{
	  /* Bring in addr_list into canonical node.  */
	  struct elt_list *last = CSELIB_VAL_PTR (loc)->addr_list;
	  while (last->next)
	    last = last->next;
	  last->next = val->addr_list;
	  val->addr_list = CSELIB_VAL_PTR (loc)->addr_list;
	  CSELIB_VAL_PTR (loc)->addr_list = NULL;
	}

      if (CSELIB_VAL_PTR (loc)->next_containing_mem != NULL
	  && val->next_containing_mem == NULL)
	{
	  /* Add VAL to the containing_mem list after LOC.  LOC will
	     be removed when we notice it doesn't contain any
	     MEMs.  */
	  val->next_containing_mem = CSELIB_VAL_PTR (loc)->next_containing_mem;
	  CSELIB_VAL_PTR (loc)->next_containing_mem = val;
	}

      /* Chain LOC back to VAL.  */
      el = elt_loc_list_pool.allocate ();
      el->loc = val->val_rtx;
      el->setting_insn = cselib_current_insn;
      el->next = NULL;
      CSELIB_VAL_PTR (loc)->locs = el;
    }

  el = elt_loc_list_pool.allocate ();
  el->loc = loc;
  el->setting_insn = cselib_current_insn;
  el->next = next;
  val->locs = el;
}

/* Promote loc L to a nondebug cselib_current_insn if L is marked as
   originating from a debug insn, maintaining the debug values
   count.  */

static inline void
promote_debug_loc (struct elt_loc_list *l)
{
  if (l && l->setting_insn && DEBUG_INSN_P (l->setting_insn)
      && (!cselib_current_insn || !DEBUG_INSN_P (cselib_current_insn)))
    {
      n_debug_values--;
      l->setting_insn = cselib_current_insn;
      if (cselib_preserve_constants && l->next)
	{
	  gcc_assert (l->next->setting_insn
		      && DEBUG_INSN_P (l->next->setting_insn)
		      && !l->next->next);
	  l->next->setting_insn = cselib_current_insn;
	}
      else
	gcc_assert (!l->next);
    }
}

/* The elt_list at *PL is no longer needed.  Unchain it and free its
   storage.  */

static inline void
unchain_one_elt_list (struct elt_list **pl)
{
  struct elt_list *l = *pl;

  *pl = l->next;
  elt_list_pool.remove (l);
}

/* Likewise for elt_loc_lists.  */

static void
unchain_one_elt_loc_list (struct elt_loc_list **pl)
{
  struct elt_loc_list *l = *pl;

  *pl = l->next;
  elt_loc_list_pool.remove (l);
}

/* Likewise for cselib_vals.  This also frees the addr_list associated with
   V.  */

static void
unchain_one_value (cselib_val *v)
{
  while (v->addr_list)
    unchain_one_elt_list (&v->addr_list);

  cselib_val_pool.remove (v);
}

/* Remove all entries from the hash table.  Also used during
   initialization.  */

void
cselib_clear_table (void)
{
  cselib_reset_table (1);
}

/* Return TRUE if V is a constant, a function invariant or a VALUE
   equivalence; FALSE otherwise.  */

static bool
invariant_or_equiv_p (cselib_val *v)
{
  struct elt_loc_list *l;

  if (v == cfa_base_preserved_val)
    return true;

  /* Keep VALUE equivalences around.  */
  for (l = v->locs; l; l = l->next)
    if (GET_CODE (l->loc) == VALUE)
      return true;

  if (v->locs != NULL
      && v->locs->next == NULL)
    {
      if (CONSTANT_P (v->locs->loc)
	  && (GET_CODE (v->locs->loc) != CONST
	      || !references_value_p (v->locs->loc, 0)))
	return true;
      /* Although a debug expr may be bound to different expressions,
	 we can preserve it as if it was constant, to get unification
	 and proper merging within var-tracking.  */
      if (GET_CODE (v->locs->loc) == DEBUG_EXPR
	  || GET_CODE (v->locs->loc) == DEBUG_IMPLICIT_PTR
	  || GET_CODE (v->locs->loc) == ENTRY_VALUE
	  || GET_CODE (v->locs->loc) == DEBUG_PARAMETER_REF)
	return true;

      /* (plus (value V) (const_int C)) is invariant iff V is invariant.  */
      if (GET_CODE (v->locs->loc) == PLUS
	  && CONST_INT_P (XEXP (v->locs->loc, 1))
	  && GET_CODE (XEXP (v->locs->loc, 0)) == VALUE
	  && invariant_or_equiv_p (CSELIB_VAL_PTR (XEXP (v->locs->loc, 0))))
	return true;
    }

  return false;
}

/* Remove from hash table all VALUEs except constants, function
   invariants and VALUE equivalences.  */

int
preserve_constants_and_equivs (cselib_val **x, void *info ATTRIBUTE_UNUSED)
{
  cselib_val *v = *x;

  if (invariant_or_equiv_p (v))
    {
      cselib_hasher::key lookup = {
	GET_MODE (v->val_rtx), v->val_rtx, VOIDmode
      };
      cselib_val **slot
	= cselib_preserved_hash_table->find_slot_with_hash (&lookup,
							   v->hash, INSERT);
      gcc_assert (!*slot);
      *slot = v;
    }

  cselib_hash_table->clear_slot (x);

  return 1;
}

/* Remove all entries from the hash table, arranging for the next
   value to be numbered NUM.  */

void
cselib_reset_table (unsigned int num)
{
  unsigned int i;

  max_value_regs = 0;

  if (cfa_base_preserved_val)
    {
      unsigned int regno = cfa_base_preserved_regno;
      unsigned int new_used_regs = 0;
      for (i = 0; i < n_used_regs; i++)
	if (used_regs[i] == regno)
	  {
	    new_used_regs = 1;
	    continue;
	  }
	else
	  REG_VALUES (used_regs[i]) = 0;
      gcc_assert (new_used_regs == 1);
      n_used_regs = new_used_regs;
      used_regs[0] = regno;
      max_value_regs
	= hard_regno_nregs (regno,
			    GET_MODE (cfa_base_preserved_val->locs->loc));
    }
  else
    {
      for (i = 0; i < n_used_regs; i++)
	REG_VALUES (used_regs[i]) = 0;
      n_used_regs = 0;
    }

  if (cselib_preserve_constants)
    cselib_hash_table->traverse <void *, preserve_constants_and_equivs>
      (NULL);
  else
    {
      cselib_hash_table->empty ();
      gcc_checking_assert (!cselib_any_perm_equivs);
    }

  n_useless_values = 0;
  n_useless_debug_values = 0;
  n_debug_values = 0;

  next_uid = num;

  first_containing_mem = &dummy_val;
}

/* Return the number of the next value that will be generated.  */

unsigned int
cselib_get_next_uid (void)
{
  return next_uid;
}

/* Search for X, whose hashcode is HASH, in CSELIB_HASH_TABLE,
   INSERTing if requested.  When X is part of the address of a MEM,
   MEMMODE should specify the mode of the MEM.  */

static cselib_val **
cselib_find_slot (machine_mode mode, rtx x, hashval_t hash,
		  enum insert_option insert, machine_mode memmode)
{
  cselib_val **slot = NULL;
  cselib_hasher::key lookup = { mode, x, memmode };
  if (cselib_preserve_constants)
    slot = cselib_preserved_hash_table->find_slot_with_hash (&lookup, hash,
							     NO_INSERT);
  if (!slot)
    slot = cselib_hash_table->find_slot_with_hash (&lookup, hash, insert);
  return slot;
}

/* Return true if X contains a VALUE rtx.  If ONLY_USELESS is set, we
   only return true for values which point to a cselib_val whose value
   element has been set to zero, which implies the cselib_val will be
   removed.  */

int
references_value_p (const_rtx x, int only_useless)
{
  const enum rtx_code code = GET_CODE (x);
  const char *fmt = GET_RTX_FORMAT (code);
  int i, j;

  if (GET_CODE (x) == VALUE
      && (! only_useless ||
	  (CSELIB_VAL_PTR (x)->locs == 0 && !PRESERVED_VALUE_P (x))))
    return 1;

  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'e' && references_value_p (XEXP (x, i), only_useless))
	return 1;
      else if (fmt[i] == 'E')
	for (j = 0; j < XVECLEN (x, i); j++)
	  if (references_value_p (XVECEXP (x, i, j), only_useless))
	    return 1;
    }

  return 0;
}

/* For all locations found in X, delete locations that reference useless
   values (i.e. values without any location).  Called through
   htab_traverse.  */

int
discard_useless_locs (cselib_val **x, void *info ATTRIBUTE_UNUSED)
{
  cselib_val *v = *x;
  struct elt_loc_list **p = &v->locs;
  bool had_locs = v->locs != NULL;
  rtx_insn *setting_insn = v->locs ? v->locs->setting_insn : NULL;

  while (*p)
    {
      if (references_value_p ((*p)->loc, 1))
	unchain_one_elt_loc_list (p);
      else
	p = &(*p)->next;
    }

  if (had_locs && v->locs == 0 && !PRESERVED_VALUE_P (v->val_rtx))
    {
      if (setting_insn && DEBUG_INSN_P (setting_insn))
	n_useless_debug_values++;
      else
	n_useless_values++;
      values_became_useless = 1;
    }
  return 1;
}

/* If X is a value with no locations, remove it from the hashtable.  */

int
discard_useless_values (cselib_val **x, void *info ATTRIBUTE_UNUSED)
{
  cselib_val *v = *x;

  if (v->locs == 0 && !PRESERVED_VALUE_P (v->val_rtx))
    {
      if (cselib_discard_hook)
	cselib_discard_hook (v);

      CSELIB_VAL_PTR (v->val_rtx) = NULL;
      cselib_hash_table->clear_slot (x);
      unchain_one_value (v);
      n_useless_values--;
    }

  return 1;
}

/* Clean out useless values (i.e. those which no longer have locations
   associated with them) from the hash table.  */

static void
remove_useless_values (void)
{
  cselib_val **p, *v;

  /* First pass: eliminate locations that reference the value.  That in
     turn can make more values useless.  */
  do
    {
      values_became_useless = 0;
      cselib_hash_table->traverse <void *, discard_useless_locs> (NULL);
    }
  while (values_became_useless);

  /* Second pass: actually remove the values.  */

  p = &first_containing_mem;
  for (v = *p; v != &dummy_val; v = v->next_containing_mem)
    if (v->locs && v == canonical_cselib_val (v))
      {
	*p = v;
	p = &(*p)->next_containing_mem;
      }
  *p = &dummy_val;

  n_useless_values += n_useless_debug_values;
  n_debug_values -= n_useless_debug_values;
  n_useless_debug_values = 0;

  cselib_hash_table->traverse <void *, discard_useless_values> (NULL);

  gcc_assert (!n_useless_values);
}

/* Arrange for a value to not be removed from the hash table even if
   it becomes useless.  */

void
cselib_preserve_value (cselib_val *v)
{
  PRESERVED_VALUE_P (v->val_rtx) = 1;
}

/* Test whether a value is preserved.  */

bool
cselib_preserved_value_p (cselib_val *v)
{
  return PRESERVED_VALUE_P (v->val_rtx);
}

/* Arrange for a REG value to be assumed constant through the whole function,
   never invalidated and preserved across cselib_reset_table calls.  */

void
cselib_preserve_cfa_base_value (cselib_val *v, unsigned int regno)
{
  if (cselib_preserve_constants
      && v->locs
      && REG_P (v->locs->loc))
    {
      cfa_base_preserved_val = v;
      cfa_base_preserved_regno = regno;
    }
}

/* Clean all non-constant expressions in the hash table, but retain
   their values.  */

void
cselib_preserve_only_values (void)
{
  int i;

  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    cselib_invalidate_regno (i, reg_raw_mode[i]);

  cselib_invalidate_mem (callmem);

  remove_useless_values ();

  gcc_assert (first_containing_mem == &dummy_val);
}

/* Arrange for a value to be marked as based on stack pointer
   for find_base_term purposes.  */

void
cselib_set_value_sp_based (cselib_val *v)
{
  SP_BASED_VALUE_P (v->val_rtx) = 1;
}

/* Test whether a value is based on stack pointer for
   find_base_term purposes.  */

bool
cselib_sp_based_value_p (cselib_val *v)
{
  return SP_BASED_VALUE_P (v->val_rtx);
}

/* Return the mode in which a register was last set.  If X is not a
   register, return its mode.  If the mode in which the register was
   set is not known, or the value was already clobbered, return
   VOIDmode.  */

machine_mode
cselib_reg_set_mode (const_rtx x)
{
  if (!REG_P (x))
    return GET_MODE (x);

  if (REG_VALUES (REGNO (x)) == NULL
      || REG_VALUES (REGNO (x))->elt == NULL)
    return VOIDmode;

  return GET_MODE (REG_VALUES (REGNO (x))->elt->val_rtx);
}

/* If x is a PLUS or an autoinc operation, expand the operation,
   storing the offset, if any, in *OFF.  */

static rtx
autoinc_split (rtx x, rtx *off, machine_mode memmode)
{
  switch (GET_CODE (x))
    {
    case PLUS:
      *off = XEXP (x, 1);
      return XEXP (x, 0);

    case PRE_DEC:
      if (memmode == VOIDmode)
	return x;

      *off = gen_int_mode (-GET_MODE_SIZE (memmode), GET_MODE (x));
      return XEXP (x, 0);

    case PRE_INC:
      if (memmode == VOIDmode)
	return x;

      *off = gen_int_mode (GET_MODE_SIZE (memmode), GET_MODE (x));
      return XEXP (x, 0);

    case PRE_MODIFY:
      return XEXP (x, 1);

    case POST_DEC:
    case POST_INC:
    case POST_MODIFY:
      return XEXP (x, 0);

    default:
      return x;
    }
}

/* Return nonzero if we can prove that X and Y contain the same value,
   taking our gathered information into account.  MEMMODE holds the
   mode of the enclosing MEM, if any, as required to deal with autoinc
   addressing modes.  If X and Y are not (known to be) part of
   addresses, MEMMODE should be VOIDmode.  */

int
rtx_equal_for_cselib_1 (rtx x, rtx y, machine_mode memmode, int depth)
{
  enum rtx_code code;
  const char *fmt;
  int i;

  if (REG_P (x) || MEM_P (x))
    {
      cselib_val *e = cselib_lookup (x, GET_MODE (x), 0, memmode);

      if (e)
	x = e->val_rtx;
    }

  if (REG_P (y) || MEM_P (y))
    {
      cselib_val *e = cselib_lookup (y, GET_MODE (y), 0, memmode);

      if (e)
	y = e->val_rtx;
    }

  if (x == y)
    return 1;

  if (GET_CODE (x) == VALUE)
    {
      cselib_val *e = canonical_cselib_val (CSELIB_VAL_PTR (x));
      struct elt_loc_list *l;

      if (GET_CODE (y) == VALUE)
	return e == canonical_cselib_val (CSELIB_VAL_PTR (y));

      if (depth == 128)
	return 0;

      for (l = e->locs; l; l = l->next)
	{
	  rtx t = l->loc;

	  /* Avoid infinite recursion.  We know we have the canonical
	     value, so we can just skip any values in the equivalence
	     list.  */
	  if (REG_P (t) || MEM_P (t) || GET_CODE (t) == VALUE)
	    continue;
	  else if (rtx_equal_for_cselib_1 (t, y, memmode, depth + 1))
	    return 1;
	}

      return 0;
    }
  else if (GET_CODE (y) == VALUE)
    {
      cselib_val *e = canonical_cselib_val (CSELIB_VAL_PTR (y));
      struct elt_loc_list *l;

      if (depth == 128)
	return 0;

      for (l = e->locs; l; l = l->next)
	{
	  rtx t = l->loc;

	  if (REG_P (t) || MEM_P (t) || GET_CODE (t) == VALUE)
	    continue;
	  else if (rtx_equal_for_cselib_1 (x, t, memmode, depth + 1))
	    return 1;
	}

      return 0;
    }

  if (GET_MODE (x) != GET_MODE (y))
    return 0;

  if (GET_CODE (x) != GET_CODE (y))
    {
      rtx xorig = x, yorig = y;
      rtx xoff = NULL, yoff = NULL;

      x = autoinc_split (x, &xoff, memmode);
      y = autoinc_split (y, &yoff, memmode);

      if (!xoff != !yoff)
	return 0;

      if (xoff && !rtx_equal_for_cselib_1 (xoff, yoff, memmode, depth))
	return 0;

      /* Don't recurse if nothing changed.  */
      if (x != xorig || y != yorig)
	return rtx_equal_for_cselib_1 (x, y, memmode, depth);

      return 0;
    }

  /* These won't be handled correctly by the code below.  */
  switch (GET_CODE (x))
    {
    CASE_CONST_UNIQUE:
    case DEBUG_EXPR:
      return 0;

    case DEBUG_IMPLICIT_PTR:
      return DEBUG_IMPLICIT_PTR_DECL (x)
	     == DEBUG_IMPLICIT_PTR_DECL (y);

    case DEBUG_PARAMETER_REF:
      return DEBUG_PARAMETER_REF_DECL (x)
	     == DEBUG_PARAMETER_REF_DECL (y);

    case ENTRY_VALUE:
      /* ENTRY_VALUEs are function invariant, it is thus undesirable to
	 use rtx_equal_for_cselib_1 to compare the operands.  */
      return rtx_equal_p (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y));

    case LABEL_REF:
      return label_ref_label (x) == label_ref_label (y);

    case REG:
      return REGNO (x) == REGNO (y);

    case MEM:
      /* We have to compare any autoinc operations in the addresses
	 using this MEM's mode.  */
      return rtx_equal_for_cselib_1 (XEXP (x, 0), XEXP (y, 0), GET_MODE (x),
				     depth);

    default:
      break;
    }

  code = GET_CODE (x);
  fmt = GET_RTX_FORMAT (code);

  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      int j;

      switch (fmt[i])
	{
	case 'w':
	  if (XWINT (x, i) != XWINT (y, i))
	    return 0;
	  break;

	case 'n':
	case 'i':
	  if (XINT (x, i) != XINT (y, i))
	    return 0;
	  break;

	case 'p':
	  if (maybe_ne (SUBREG_BYTE (x), SUBREG_BYTE (y)))
	    return 0;
	  break;

	case 'V':
	case 'E':
	  /* Two vectors must have the same length.  */
	  if (XVECLEN (x, i) != XVECLEN (y, i))
	    return 0;

	  /* And the corresponding elements must match.  */
	  for (j = 0; j < XVECLEN (x, i); j++)
	    if (! rtx_equal_for_cselib_1 (XVECEXP (x, i, j),
					  XVECEXP (y, i, j), memmode, depth))
	      return 0;
	  break;

	case 'e':
	  if (i == 1
	      && targetm.commutative_p (x, UNKNOWN)
	      && rtx_equal_for_cselib_1 (XEXP (x, 1), XEXP (y, 0), memmode,
					 depth)
	      && rtx_equal_for_cselib_1 (XEXP (x, 0), XEXP (y, 1), memmode,
					 depth))
	    return 1;
	  if (! rtx_equal_for_cselib_1 (XEXP (x, i), XEXP (y, i), memmode,
					depth))
	    return 0;
	  break;

	case 'S':
	case 's':
	  if (strcmp (XSTR (x, i), XSTR (y, i)))
	    return 0;
	  break;

	case 'u':
	  /* These are just backpointers, so they don't matter.  */
	  break;

	case '0':
	case 't':
	  break;

	  /* It is believed that rtx's at this level will never
	     contain anything but integers and other rtx's,
	     except for within LABEL_REFs and SYMBOL_REFs.  */
	default:
	  gcc_unreachable ();
	}
    }
  return 1;
}

/* Hash an rtx.  Return 0 if we couldn't hash the rtx.
   For registers and memory locations, we look up their cselib_val structure
   and return its VALUE element.
   Possible reasons for return 0 are: the object is volatile, or we couldn't
   find a register or memory location in the table and CREATE is zero.  If
   CREATE is nonzero, table elts are created for regs and mem.
   N.B. this hash function returns the same hash value for RTXes that
   differ only in the order of operands, thus it is suitable for comparisons
   that take commutativity into account.
   If we wanted to also support associative rules, we'd have to use a different
   strategy to avoid returning spurious 0, e.g. return ~(~0U >> 1) .
   MEMMODE indicates the mode of an enclosing MEM, and it's only
   used to compute autoinc values.
   We used to have a MODE argument for hashing for CONST_INTs, but that
   didn't make sense, since it caused spurious hash differences between
    (set (reg:SI 1) (const_int))
    (plus:SI (reg:SI 2) (reg:SI 1))
   and
    (plus:SI (reg:SI 2) (const_int))
   If the mode is important in any context, it must be checked specifically
   in a comparison anyway, since relying on hash differences is unsafe.  */

static unsigned int
cselib_hash_rtx (rtx x, int create, machine_mode memmode)
{
  cselib_val *e;
  poly_int64 offset;
  int i, j;
  enum rtx_code code;
  const char *fmt;
  unsigned int hash = 0;

  code = GET_CODE (x);
  hash += (unsigned) code + (unsigned) GET_MODE (x);

  switch (code)
    {
    case VALUE:
      e = CSELIB_VAL_PTR (x);
      return e->hash;

    case MEM:
    case REG:
      e = cselib_lookup (x, GET_MODE (x), create, memmode);
      if (! e)
	return 0;

      return e->hash;

    case DEBUG_EXPR:
      hash += ((unsigned) DEBUG_EXPR << 7)
	      + DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x));
      return hash ? hash : (unsigned int) DEBUG_EXPR;

    case DEBUG_IMPLICIT_PTR:
      hash += ((unsigned) DEBUG_IMPLICIT_PTR << 7)
	      + DECL_UID (DEBUG_IMPLICIT_PTR_DECL (x));
      return hash ? hash : (unsigned int) DEBUG_IMPLICIT_PTR;

    case DEBUG_PARAMETER_REF:
      hash += ((unsigned) DEBUG_PARAMETER_REF << 7)
	      + DECL_UID (DEBUG_PARAMETER_REF_DECL (x));
      return hash ? hash : (unsigned int) DEBUG_PARAMETER_REF;

    case ENTRY_VALUE:
      /* ENTRY_VALUEs are function invariant, thus try to avoid
	 recursing on argument if ENTRY_VALUE is one of the
	 forms emitted by expand_debug_expr, otherwise
	 ENTRY_VALUE hash would depend on the current value
	 in some register or memory.  */
      if (REG_P (ENTRY_VALUE_EXP (x)))
	hash += (unsigned int) REG
		+ (unsigned int) GET_MODE (ENTRY_VALUE_EXP (x))
		+ (unsigned int) REGNO (ENTRY_VALUE_EXP (x));
      else if (MEM_P (ENTRY_VALUE_EXP (x))
	       && REG_P (XEXP (ENTRY_VALUE_EXP (x), 0)))
	hash += (unsigned int) MEM
		+ (unsigned int) GET_MODE (XEXP (ENTRY_VALUE_EXP (x), 0))
		+ (unsigned int) REGNO (XEXP (ENTRY_VALUE_EXP (x), 0));
      else
	hash += cselib_hash_rtx (ENTRY_VALUE_EXP (x), create, memmode);
      return hash ? hash : (unsigned int) ENTRY_VALUE;

    case CONST_INT:
      hash += ((unsigned) CONST_INT << 7) + UINTVAL (x);
      return hash ? hash : (unsigned int) CONST_INT;

    case CONST_WIDE_INT:
      for (i = 0; i < CONST_WIDE_INT_NUNITS (x); i++)
	hash += CONST_WIDE_INT_ELT (x, i);
      return hash;

    case CONST_POLY_INT:
      {
	inchash::hash h;
	h.add_int (hash);
	for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
	  h.add_wide_int (CONST_POLY_INT_COEFFS (x)[i]);
	return h.end ();
      }

    case CONST_DOUBLE:
      /* This is like the general case, except that it only counts
	 the integers representing the constant.  */
      hash += (unsigned) code + (unsigned) GET_MODE (x);
      if (TARGET_SUPPORTS_WIDE_INT == 0 && GET_MODE (x) == VOIDmode)
	hash += ((unsigned) CONST_DOUBLE_LOW (x)
		 + (unsigned) CONST_DOUBLE_HIGH (x));
      else
	hash += real_hash (CONST_DOUBLE_REAL_VALUE (x));
      return hash ? hash : (unsigned int) CONST_DOUBLE;

    case CONST_FIXED:
      hash += (unsigned int) code + (unsigned int) GET_MODE (x);
      hash += fixed_hash (CONST_FIXED_VALUE (x));
      return hash ? hash : (unsigned int) CONST_FIXED;

    case CONST_VECTOR:
      {
	int units;
	rtx elt;

	units = const_vector_encoded_nelts (x);

	for (i = 0; i < units; ++i)
	  {
	    elt = CONST_VECTOR_ENCODED_ELT (x, i);
	    hash += cselib_hash_rtx (elt, 0, memmode);
	  }

	return hash;
      }

      /* Assume there is only one rtx object for any given label.  */
    case LABEL_REF:
      /* We don't hash on the address of the CODE_LABEL to avoid bootstrap
	 differences and differences between each stage's debugging dumps.  */
      hash += (((unsigned int) LABEL_REF << 7)
	       + CODE_LABEL_NUMBER (label_ref_label (x)));
      return hash ? hash : (unsigned int) LABEL_REF;

    case SYMBOL_REF:
      {
	/* Don't hash on the symbol's address to avoid bootstrap differences.
	   Different hash values may cause expressions to be recorded in
	   different orders and thus different registers to be used in the
	   final assembler.  This also avoids differences in the dump files
	   between various stages.  */
	unsigned int h = 0;
	const unsigned char *p = (const unsigned char *) XSTR (x, 0);

	while (*p)
	  h += (h << 7) + *p++; /* ??? revisit */

	hash += ((unsigned int) SYMBOL_REF << 7) + h;
	return hash ? hash : (unsigned int) SYMBOL_REF;
      }

    case PRE_DEC:
    case PRE_INC:
      /* We can't compute these without knowing the MEM mode.  */
      gcc_assert (memmode != VOIDmode);
      offset = GET_MODE_SIZE (memmode);
      if (code == PRE_DEC)
	offset = -offset;
      /* Adjust the hash so that (mem:MEMMODE (pre_* (reg))) hashes
	 like (mem:MEMMODE (plus (reg) (const_int I))).  */
      hash += (unsigned) PLUS - (unsigned)code
	+ cselib_hash_rtx (XEXP (x, 0), create, memmode)
	+ cselib_hash_rtx (gen_int_mode (offset, GET_MODE (x)),
			   create, memmode);
      return hash ? hash : 1 + (unsigned) PLUS;

    case PRE_MODIFY:
      gcc_assert (memmode != VOIDmode);
      return cselib_hash_rtx (XEXP (x, 1), create, memmode);

    case POST_DEC:
    case POST_INC:
    case POST_MODIFY:
      gcc_assert (memmode != VOIDmode);
      return cselib_hash_rtx (XEXP (x, 0), create, memmode);

    case PC:
    case CC0:
    case CALL:
    case UNSPEC_VOLATILE:
      return 0;

    case ASM_OPERANDS:
      if (MEM_VOLATILE_P (x))
	return 0;

      break;

    default:
      break;
    }

  i = GET_RTX_LENGTH (code) - 1;
  fmt = GET_RTX_FORMAT (code);
  for (; i >= 0; i--)
    {
      switch (fmt[i])
	{
	case 'e':
	  {
	    rtx tem = XEXP (x, i);
	    unsigned int tem_hash = cselib_hash_rtx (tem, create, memmode);

	    if (tem_hash == 0)
	      return 0;

	    hash += tem_hash;
	  }
	  break;
	case 'E':
	  for (j = 0; j < XVECLEN (x, i); j++)
	    {
	      unsigned int tem_hash
		= cselib_hash_rtx (XVECEXP (x, i, j), create, memmode);

	      if (tem_hash == 0)
		return 0;

	      hash += tem_hash;
	    }
	  break;

	case 's':
	  {
	    const unsigned char *p = (const unsigned char *) XSTR (x, i);

	    if (p)
	      while (*p)
		hash += *p++;
	    break;
	  }

	case 'i':
	  hash += XINT (x, i);
	  break;

	case 'p':
	  hash += constant_lower_bound (SUBREG_BYTE (x));
	  break;

	case '0':
	case 't':
	  /* unused */
	  break;

	default:
	  gcc_unreachable ();
	}
    }

  return hash ? hash : 1 + (unsigned int) GET_CODE (x);
}

/* Create a new value structure for VALUE and initialize it.  The mode of the
   value is MODE.  */

static inline cselib_val *
new_cselib_val (unsigned int hash, machine_mode mode, rtx x)
{
  cselib_val *e = cselib_val_pool.allocate ();

  gcc_assert (hash);
  gcc_assert (next_uid);

  e->hash = hash;
  e->uid = next_uid++;
  /* We use an alloc pool to allocate this RTL construct because it
     accounts for about 8% of the overall memory usage.  We know
     precisely when we can have VALUE RTXen (when cselib is active)
     so we don't need to put them in garbage collected memory.
     ??? Why should a VALUE be an RTX in the first place?  */
  e->val_rtx = (rtx_def*) value_pool.allocate ();
  memset (e->val_rtx, 0, RTX_HDR_SIZE);
  PUT_CODE (e->val_rtx, VALUE);
  PUT_MODE (e->val_rtx, mode);
  CSELIB_VAL_PTR (e->val_rtx) = e;
  e->addr_list = 0;
  e->locs = 0;
  e->next_containing_mem = 0;

  if (dump_file && (dump_flags & TDF_CSELIB))
    {
      fprintf (dump_file, "cselib value %u:%u ", e->uid, hash);
      if (flag_dump_noaddr || flag_dump_unnumbered)
	fputs ("# ", dump_file);
      else
	fprintf (dump_file, "%p ", (void*)e);
      print_rtl_single (dump_file, x);
      fputc ('\n', dump_file);
    }

  return e;
}

/* ADDR_ELT is a value that is used as address.  MEM_ELT is the value that
   contains the data at this address.  X is a MEM that represents the
   value.  Update the two value structures to represent this situation.  */

static void
add_mem_for_addr (cselib_val *addr_elt, cselib_val *mem_elt, rtx x)
{
  addr_elt = canonical_cselib_val (addr_elt);
  mem_elt = canonical_cselib_val (mem_elt);

  /* Avoid duplicates.  */
  addr_space_t as = MEM_ADDR_SPACE (x);
  for (elt_loc_list *l = mem_elt->locs; l; l = l->next)
    if (MEM_P (l->loc)
	&& CSELIB_VAL_PTR (XEXP (l->loc, 0)) == addr_elt
        && MEM_ADDR_SPACE (l->loc) == as)
      {
	promote_debug_loc (l);
	return;
      }

  addr_elt->addr_list = new_elt_list (addr_elt->addr_list, mem_elt);
  new_elt_loc_list (mem_elt,
		    replace_equiv_address_nv (x, addr_elt->val_rtx));
  if (mem_elt->next_containing_mem == NULL)
    {
      mem_elt->next_containing_mem = first_containing_mem;
      first_containing_mem = mem_elt;
    }
}

/* Subroutine of cselib_lookup.  Return a value for X, which is a MEM rtx.
   If CREATE, make a new one if we haven't seen it before.  */

static cselib_val *
cselib_lookup_mem (rtx x, int create)
{
  machine_mode mode = GET_MODE (x);
  machine_mode addr_mode;
  cselib_val **slot;
  cselib_val *addr;
  cselib_val *mem_elt;

  if (MEM_VOLATILE_P (x) || mode == BLKmode
      || !cselib_record_memory
      || (FLOAT_MODE_P (mode) && flag_float_store))
    return 0;

  addr_mode = GET_MODE (XEXP (x, 0));
  if (addr_mode == VOIDmode)
    addr_mode = Pmode;

  /* Look up the value for the address.  */
  addr = cselib_lookup (XEXP (x, 0), addr_mode, create, mode);
  if (! addr)
    return 0;
  addr = canonical_cselib_val (addr);

  /* Find a value that describes a value of our mode at that address.  */
  addr_space_t as = MEM_ADDR_SPACE (x);
  for (elt_list *l = addr->addr_list; l; l = l->next)
    if (GET_MODE (l->elt->val_rtx) == mode)
      {
	for (elt_loc_list *l2 = l->elt->locs; l2; l2 = l2->next)
	  if (MEM_P (l2->loc) && MEM_ADDR_SPACE (l2->loc) == as)
	    {
	      promote_debug_loc (l->elt->locs);
	      return l->elt;
	    }
      }

  if (! create)
    return 0;

  mem_elt = new_cselib_val (next_uid, mode, x);
  add_mem_for_addr (addr, mem_elt, x);
  slot = cselib_find_slot (mode, x, mem_elt->hash, INSERT, VOIDmode);
  *slot = mem_elt;
  return mem_elt;
}

/* Search through the possible substitutions in P.  We prefer a non reg
   substitution because this allows us to expand the tree further.  If
   we find, just a reg, take the lowest regno.  There may be several
   non-reg results, we just take the first one because they will all
   expand to the same place.  */

static rtx
expand_loc (struct elt_loc_list *p, struct expand_value_data *evd,
	    int max_depth)
{
  rtx reg_result = NULL;
  unsigned int regno = UINT_MAX;
  struct elt_loc_list *p_in = p;

  for (; p; p = p->next)
    {
      /* Return these right away to avoid returning stack pointer based
	 expressions for frame pointer and vice versa, which is something
	 that would confuse DSE.  See the comment in cselib_expand_value_rtx_1
	 for more details.  */
      if (REG_P (p->loc)
	  && (REGNO (p->loc) == STACK_POINTER_REGNUM
	      || REGNO (p->loc) == FRAME_POINTER_REGNUM
	      || REGNO (p->loc) == HARD_FRAME_POINTER_REGNUM
	      || REGNO (p->loc) == cfa_base_preserved_regno))
	return p->loc;
      /* Avoid infinite recursion trying to expand a reg into a
	 the same reg.  */
      if ((REG_P (p->loc))
	  && (REGNO (p->loc) < regno)
	  && !bitmap_bit_p (evd->regs_active, REGNO (p->loc)))
	{
	  reg_result = p->loc;
	  regno = REGNO (p->loc);
	}
      /* Avoid infinite recursion and do not try to expand the
	 value.  */
      else if (GET_CODE (p->loc) == VALUE
	       && CSELIB_VAL_PTR (p->loc)->locs == p_in)
	continue;
      else if (!REG_P (p->loc))
	{
	  rtx result, note;
	  if (dump_file && (dump_flags & TDF_CSELIB))
	    {
	      print_inline_rtx (dump_file, p->loc, 0);
	      fprintf (dump_file, "\n");
	    }
	  if (GET_CODE (p->loc) == LO_SUM
	      && GET_CODE (XEXP (p->loc, 1)) == SYMBOL_REF
	      && p->setting_insn
	      && (note = find_reg_note (p->setting_insn, REG_EQUAL, NULL_RTX))
	      && XEXP (note, 0) == XEXP (p->loc, 1))
	    return XEXP (p->loc, 1);
	  result = cselib_expand_value_rtx_1 (p->loc, evd, max_depth - 1);
	  if (result)
	    return result;
	}

    }

  if (regno != UINT_MAX)
    {
      rtx result;
      if (dump_file && (dump_flags & TDF_CSELIB))
	fprintf (dump_file, "r%d\n", regno);

      result = cselib_expand_value_rtx_1 (reg_result, evd, max_depth - 1);
      if (result)
	return result;
    }

  if (dump_file && (dump_flags & TDF_CSELIB))
    {
      if (reg_result)
	{
	  print_inline_rtx (dump_file, reg_result, 0);
	  fprintf (dump_file, "\n");
	}
      else
	fprintf (dump_file, "NULL\n");
    }
  return reg_result;
}


/* Forward substitute and expand an expression out to its roots.
   This is the opposite of common subexpression.  Because local value
   numbering is such a weak optimization, the expanded expression is
   pretty much unique (not from a pointer equals point of view but
   from a tree shape point of view.

   This function returns NULL if the expansion fails.  The expansion
   will fail if there is no value number for one of the operands or if
   one of the operands has been overwritten between the current insn
   and the beginning of the basic block.  For instance x has no
   expansion in:

   r1 <- r1 + 3
   x <- r1 + 8

   REGS_ACTIVE is a scratch bitmap that should be clear when passing in.
   It is clear on return.  */

rtx
cselib_expand_value_rtx (rtx orig, bitmap regs_active, int max_depth)
{
  struct expand_value_data evd;

  evd.regs_active = regs_active;
  evd.callback = NULL;
  evd.callback_arg = NULL;
  evd.dummy = false;

  return cselib_expand_value_rtx_1 (orig, &evd, max_depth);
}

/* Same as cselib_expand_value_rtx, but using a callback to try to
   resolve some expressions.  The CB function should return ORIG if it
   can't or does not want to deal with a certain RTX.  Any other
   return value, including NULL, will be used as the expansion for
   VALUE, without any further changes.  */

rtx
cselib_expand_value_rtx_cb (rtx orig, bitmap regs_active, int max_depth,
			    cselib_expand_callback cb, void *data)
{
  struct expand_value_data evd;

  evd.regs_active = regs_active;
  evd.callback = cb;
  evd.callback_arg = data;
  evd.dummy = false;

  return cselib_expand_value_rtx_1 (orig, &evd, max_depth);
}

/* Similar to cselib_expand_value_rtx_cb, but no rtxs are actually copied
   or simplified.  Useful to find out whether cselib_expand_value_rtx_cb
   would return NULL or non-NULL, without allocating new rtx.  */

bool
cselib_dummy_expand_value_rtx_cb (rtx orig, bitmap regs_active, int max_depth,
				  cselib_expand_callback cb, void *data)
{
  struct expand_value_data evd;

  evd.regs_active = regs_active;
  evd.callback = cb;
  evd.callback_arg = data;
  evd.dummy = true;

  return cselib_expand_value_rtx_1 (orig, &evd, max_depth) != NULL;
}

/* Internal implementation of cselib_expand_value_rtx and
   cselib_expand_value_rtx_cb.  */

static rtx
cselib_expand_value_rtx_1 (rtx orig, struct expand_value_data *evd,
			   int max_depth)
{
  rtx copy, scopy;
  int i, j;
  RTX_CODE code;
  const char *format_ptr;
  machine_mode mode;

  code = GET_CODE (orig);

  /* For the context of dse, if we end up expand into a huge tree, we
     will not have a useful address, so we might as well just give up
     quickly.  */
  if (max_depth <= 0)
    return NULL;

  switch (code)
    {
    case REG:
      {
	struct elt_list *l = REG_VALUES (REGNO (orig));

	if (l && l->elt == NULL)
	  l = l->next;
	for (; l; l = l->next)
	  if (GET_MODE (l->elt->val_rtx) == GET_MODE (orig))
	    {
	      rtx result;
	      unsigned regno = REGNO (orig);

	      /* The only thing that we are not willing to do (this
		 is requirement of dse and if others potential uses
		 need this function we should add a parm to control
		 it) is that we will not substitute the
		 STACK_POINTER_REGNUM, FRAME_POINTER or the
		 HARD_FRAME_POINTER.

		 These expansions confuses the code that notices that
		 stores into the frame go dead at the end of the
		 function and that the frame is not effected by calls
		 to subroutines.  If you allow the
		 STACK_POINTER_REGNUM substitution, then dse will
		 think that parameter pushing also goes dead which is
		 wrong.  If you allow the FRAME_POINTER or the
		 HARD_FRAME_POINTER then you lose the opportunity to
		 make the frame assumptions.  */
	      if (regno == STACK_POINTER_REGNUM
		  || regno == FRAME_POINTER_REGNUM
		  || regno == HARD_FRAME_POINTER_REGNUM
		  || regno == cfa_base_preserved_regno)
		return orig;

	      bitmap_set_bit (evd->regs_active, regno);

	      if (dump_file && (dump_flags & TDF_CSELIB))
		fprintf (dump_file, "expanding: r%d into: ", regno);

	      result = expand_loc (l->elt->locs, evd, max_depth);
	      bitmap_clear_bit (evd->regs_active, regno);

	      if (result)
		return result;
	      else
		return orig;
	    }
	return orig;
      }

    CASE_CONST_ANY:
    case SYMBOL_REF:
    case CODE_LABEL:
    case PC:
    case CC0:
    case SCRATCH:
      /* SCRATCH must be shared because they represent distinct values.  */
      return orig;
    case CLOBBER:
      if (REG_P (XEXP (orig, 0)) && HARD_REGISTER_NUM_P (REGNO (XEXP (orig, 0))))
	return orig;
      break;

    case CONST:
      if (shared_const_p (orig))
	return orig;
      break;

    case SUBREG:
      {
	rtx subreg;

	if (evd->callback)
	  {
	    subreg = evd->callback (orig, evd->regs_active, max_depth,
				    evd->callback_arg);
	    if (subreg != orig)
	      return subreg;
	  }

	subreg = cselib_expand_value_rtx_1 (SUBREG_REG (orig), evd,
					    max_depth - 1);
	if (!subreg)
	  return NULL;
	scopy = simplify_gen_subreg (GET_MODE (orig), subreg,
				     GET_MODE (SUBREG_REG (orig)),
				     SUBREG_BYTE (orig));
	if (scopy == NULL
	    || (GET_CODE (scopy) == SUBREG
		&& !REG_P (SUBREG_REG (scopy))
		&& !MEM_P (SUBREG_REG (scopy))))
	  return NULL;

	return scopy;
      }

    case VALUE:
      {
	rtx result;

	if (dump_file && (dump_flags & TDF_CSELIB))
	  {
	    fputs ("\nexpanding ", dump_file);
	    print_rtl_single (dump_file, orig);
	    fputs (" into...", dump_file);
	  }

	if (evd->callback)
	  {
	    result = evd->callback (orig, evd->regs_active, max_depth,
				    evd->callback_arg);

	    if (result != orig)
	      return result;
	  }

	result = expand_loc (CSELIB_VAL_PTR (orig)->locs, evd, max_depth);
	return result;
      }

    case DEBUG_EXPR:
      if (evd->callback)
	return evd->callback (orig, evd->regs_active, max_depth,
			      evd->callback_arg);
      return orig;

    default:
      break;
    }

  /* Copy the various flags, fields, and other information.  We assume
     that all fields need copying, and then clear the fields that should
     not be copied.  That is the sensible default behavior, and forces
     us to explicitly document why we are *not* copying a flag.  */
  if (evd->dummy)
    copy = NULL;
  else
    copy = shallow_copy_rtx (orig);

  format_ptr = GET_RTX_FORMAT (code);

  for (i = 0; i < GET_RTX_LENGTH (code); i++)
    switch (*format_ptr++)
      {
      case 'e':
	if (XEXP (orig, i) != NULL)
	  {
	    rtx result = cselib_expand_value_rtx_1 (XEXP (orig, i), evd,
						    max_depth - 1);
	    if (!result)
	      return NULL;
	    if (copy)
	      XEXP (copy, i) = result;
	  }
	break;

      case 'E':
      case 'V':
	if (XVEC (orig, i) != NULL)
	  {
	    if (copy)
	      XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
	    for (j = 0; j < XVECLEN (orig, i); j++)
	      {
		rtx result = cselib_expand_value_rtx_1 (XVECEXP (orig, i, j),
							evd, max_depth - 1);
		if (!result)
		  return NULL;
		if (copy)
		  XVECEXP (copy, i, j) = result;
	      }
	  }
	break;

      case 't':
      case 'w':
      case 'i':
      case 's':
      case 'S':
      case 'T':
      case 'u':
      case 'B':
      case '0':
	/* These are left unchanged.  */
	break;

      default:
	gcc_unreachable ();
      }

  if (evd->dummy)
    return orig;

  mode = GET_MODE (copy);
  /* If an operand has been simplified into CONST_INT, which doesn't
     have a mode and the mode isn't derivable from whole rtx's mode,
     try simplify_*_operation first with mode from original's operand
     and as a fallback wrap CONST_INT into gen_rtx_CONST.  */
  scopy = copy;
  switch (GET_RTX_CLASS (code))
    {
    case RTX_UNARY:
      if (CONST_INT_P (XEXP (copy, 0))
	  && GET_MODE (XEXP (orig, 0)) != VOIDmode)
	{
	  scopy = simplify_unary_operation (code, mode, XEXP (copy, 0),
					    GET_MODE (XEXP (orig, 0)));
	  if (scopy)
	    return scopy;
	}
      break;
    case RTX_COMM_ARITH:
    case RTX_BIN_ARITH:
      /* These expressions can derive operand modes from the whole rtx's mode.  */
      break;
    case RTX_TERNARY:
    case RTX_BITFIELD_OPS:
      if (CONST_INT_P (XEXP (copy, 0))
	  && GET_MODE (XEXP (orig, 0)) != VOIDmode)
	{
	  scopy = simplify_ternary_operation (code, mode,
					      GET_MODE (XEXP (orig, 0)),
					      XEXP (copy, 0), XEXP (copy, 1),
					      XEXP (copy, 2));
	  if (scopy)
	    return scopy;
	}
      break;
    case RTX_COMPARE:
    case RTX_COMM_COMPARE:
      if (CONST_INT_P (XEXP (copy, 0))
	  && GET_MODE (XEXP (copy, 1)) == VOIDmode
	  && (GET_MODE (XEXP (orig, 0)) != VOIDmode
	      || GET_MODE (XEXP (orig, 1)) != VOIDmode))
	{
	  scopy = simplify_relational_operation (code, mode,
						 (GET_MODE (XEXP (orig, 0))
						  != VOIDmode)
						 ? GET_MODE (XEXP (orig, 0))
						 : GET_MODE (XEXP (orig, 1)),
						 XEXP (copy, 0),
						 XEXP (copy, 1));
	  if (scopy)
	    return scopy;
	}
      break;
    default:
      break;
    }
  scopy = simplify_rtx (copy);
  if (scopy)
    return scopy;
  return copy;
}

/* Walk rtx X and replace all occurrences of REG and MEM subexpressions
   with VALUE expressions.  This way, it becomes independent of changes
   to registers and memory.
   X isn't actually modified; if modifications are needed, new rtl is
   allocated.  However, the return value can share rtl with X.
   If X is within a MEM, MEMMODE must be the mode of the MEM.  */

rtx
cselib_subst_to_values (rtx x, machine_mode memmode)
{
  enum rtx_code code = GET_CODE (x);
  const char *fmt = GET_RTX_FORMAT (code);
  cselib_val *e;
  struct elt_list *l;
  rtx copy = x;
  int i;
  poly_int64 offset;

  switch (code)
    {
    case REG:
      l = REG_VALUES (REGNO (x));
      if (l && l->elt == NULL)
	l = l->next;
      for (; l; l = l->next)
	if (GET_MODE (l->elt->val_rtx) == GET_MODE (x))
	  return l->elt->val_rtx;

      gcc_unreachable ();

    case MEM:
      e = cselib_lookup_mem (x, 0);
      /* This used to happen for autoincrements, but we deal with them
	 properly now.  Remove the if stmt for the next release.  */
      if (! e)
	{
	  /* Assign a value that doesn't match any other.  */
	  e = new_cselib_val (next_uid, GET_MODE (x), x);
	}
      return e->val_rtx;

    case ENTRY_VALUE:
      e = cselib_lookup (x, GET_MODE (x), 0, memmode);
      if (! e)
	break;
      return e->val_rtx;

    CASE_CONST_ANY:
      return x;

    case PRE_DEC:
    case PRE_INC:
      gcc_assert (memmode != VOIDmode);
      offset = GET_MODE_SIZE (memmode);
      if (code == PRE_DEC)
	offset = -offset;
      return cselib_subst_to_values (plus_constant (GET_MODE (x),
						    XEXP (x, 0), offset),
				     memmode);

    case PRE_MODIFY:
      gcc_assert (memmode != VOIDmode);
      return cselib_subst_to_values (XEXP (x, 1), memmode);

    case POST_DEC:
    case POST_INC:
    case POST_MODIFY:
      gcc_assert (memmode != VOIDmode);
      return cselib_subst_to_values (XEXP (x, 0), memmode);

    default:
      break;
    }

  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'e')
	{
	  rtx t = cselib_subst_to_values (XEXP (x, i), memmode);

	  if (t != XEXP (x, i))
	    {
	      if (x == copy)
		copy = shallow_copy_rtx (x);
	      XEXP (copy, i) = t;
	    }
	}
      else if (fmt[i] == 'E')
	{
	  int j;

	  for (j = 0; j < XVECLEN (x, i); j++)
	    {
	      rtx t = cselib_subst_to_values (XVECEXP (x, i, j), memmode);

	      if (t != XVECEXP (x, i, j))
		{
		  if (XVEC (x, i) == XVEC (copy, i))
		    {
		      if (x == copy)
			copy = shallow_copy_rtx (x);
		      XVEC (copy, i) = shallow_copy_rtvec (XVEC (x, i));
		    }
		  XVECEXP (copy, i, j) = t;
		}
	    }
	}
    }

  return copy;
}

/* Wrapper for cselib_subst_to_values, that indicates X is in INSN.  */

rtx
cselib_subst_to_values_from_insn (rtx x, machine_mode memmode, rtx_insn *insn)
{
  rtx ret;
  gcc_assert (!cselib_current_insn);
  cselib_current_insn = insn;
  ret = cselib_subst_to_values (x, memmode);
  cselib_current_insn = NULL;
  return ret;
}

/* Look up the rtl expression X in our tables and return the value it
   has.  If CREATE is zero, we return NULL if we don't know the value.
   Otherwise, we create a new one if possible, using mode MODE if X
   doesn't have a mode (i.e. because it's a constant).  When X is part
   of an address, MEMMODE should be the mode of the enclosing MEM if
   we're tracking autoinc expressions.  */

static cselib_val *
cselib_lookup_1 (rtx x, machine_mode mode,
		 int create, machine_mode memmode)
{
  cselib_val **slot;
  cselib_val *e;
  unsigned int hashval;

  if (GET_MODE (x) != VOIDmode)
    mode = GET_MODE (x);

  if (GET_CODE (x) == VALUE)
    return CSELIB_VAL_PTR (x);

  if (REG_P (x))
    {
      struct elt_list *l;
      unsigned int i = REGNO (x);

      l = REG_VALUES (i);
      if (l && l->elt == NULL)
	l = l->next;
      for (; l; l = l->next)
	if (mode == GET_MODE (l->elt->val_rtx))
	  {
	    promote_debug_loc (l->elt->locs);
	    return l->elt;
	  }

      if (! create)
	return 0;

      if (i < FIRST_PSEUDO_REGISTER)
	{
	  unsigned int n = hard_regno_nregs (i, mode);

	  if (n > max_value_regs)
	    max_value_regs = n;
	}

      e = new_cselib_val (next_uid, GET_MODE (x), x);
      new_elt_loc_list (e, x);

      scalar_int_mode int_mode;
      if (REG_VALUES (i) == 0)
	{
	  /* Maintain the invariant that the first entry of
	     REG_VALUES, if present, must be the value used to set the
	     register, or NULL.  */
	  used_regs[n_used_regs++] = i;
	  REG_VALUES (i) = new_elt_list (REG_VALUES (i), NULL);
	}
      else if (cselib_preserve_constants
	       && is_int_mode (mode, &int_mode))
	{
	  /* During var-tracking, try harder to find equivalences
	     for SUBREGs.  If a setter sets say a DImode register
	     and user uses that register only in SImode, add a lowpart
	     subreg location.  */
	  struct elt_list *lwider = NULL;
	  scalar_int_mode lmode;
	  l = REG_VALUES (i);
	  if (l && l->elt == NULL)
	    l = l->next;
	  for (; l; l = l->next)
	    if (is_int_mode (GET_MODE (l->elt->val_rtx), &lmode)
		&& GET_MODE_SIZE (lmode) > GET_MODE_SIZE (int_mode)
		&& (lwider == NULL
		    || partial_subreg_p (lmode,
					 GET_MODE (lwider->elt->val_rtx))))
	      {
		struct elt_loc_list *el;
		if (i < FIRST_PSEUDO_REGISTER
		    && hard_regno_nregs (i, lmode) != 1)
		  continue;
		for (el = l->elt->locs; el; el = el->next)
		  if (!REG_P (el->loc))
		    break;
		if (el)
		  lwider = l;
	      }
	  if (lwider)
	    {
	      rtx sub = lowpart_subreg (int_mode, lwider->elt->val_rtx,
					GET_MODE (lwider->elt->val_rtx));
	      if (sub)
		new_elt_loc_list (e, sub);
	    }
	}
      REG_VALUES (i)->next = new_elt_list (REG_VALUES (i)->next, e);
      slot = cselib_find_slot (mode, x, e->hash, INSERT, memmode);
      *slot = e;
      return e;
    }

  if (MEM_P (x))
    return cselib_lookup_mem (x, create);

  hashval = cselib_hash_rtx (x, create, memmode);
  /* Can't even create if hashing is not possible.  */
  if (! hashval)
    return 0;

  slot = cselib_find_slot (mode, x, hashval,
			   create ? INSERT : NO_INSERT, memmode);
  if (slot == 0)
    return 0;

  e = (cselib_val *) *slot;
  if (e)
    return e;

  e = new_cselib_val (hashval, mode, x);

  /* We have to fill the slot before calling cselib_subst_to_values:
     the hash table is inconsistent until we do so, and
     cselib_subst_to_values will need to do lookups.  */
  *slot = e;
  new_elt_loc_list (e, cselib_subst_to_values (x, memmode));
  return e;
}

/* Wrapper for cselib_lookup, that indicates X is in INSN.  */

cselib_val *
cselib_lookup_from_insn (rtx x, machine_mode mode,
			 int create, machine_mode memmode, rtx_insn *insn)
{
  cselib_val *ret;

  gcc_assert (!cselib_current_insn);
  cselib_current_insn = insn;

  ret = cselib_lookup (x, mode, create, memmode);

  cselib_current_insn = NULL;

  return ret;
}

/* Wrapper for cselib_lookup_1, that logs the lookup result and
   maintains invariants related with debug insns.  */

cselib_val *
cselib_lookup (rtx x, machine_mode mode,
	       int create, machine_mode memmode)
{
  cselib_val *ret = cselib_lookup_1 (x, mode, create, memmode);

  /* ??? Should we return NULL if we're not to create an entry, the
     found loc is a debug loc and cselib_current_insn is not DEBUG?
     If so, we should also avoid converting val to non-DEBUG; probably
     easiest setting cselib_current_insn to NULL before the call
     above.  */

  if (dump_file && (dump_flags & TDF_CSELIB))
    {
      fputs ("cselib lookup ", dump_file);
      print_inline_rtx (dump_file, x, 2);
      fprintf (dump_file, " => %u:%u\n",
	       ret ? ret->uid : 0,
	       ret ? ret->hash : 0);
    }

  return ret;
}

/* Invalidate any entries in reg_values that overlap REGNO.  This is called
   if REGNO is changing.  MODE is the mode of the assignment to REGNO, which
   is used to determine how many hard registers are being changed.  If MODE
   is VOIDmode, then only REGNO is being changed; this is used when
   invalidating call clobbered registers across a call.  */

static void
cselib_invalidate_regno (unsigned int regno, machine_mode mode)
{
  unsigned int endregno;
  unsigned int i;

  /* If we see pseudos after reload, something is _wrong_.  */
  gcc_assert (!reload_completed || regno < FIRST_PSEUDO_REGISTER
	      || reg_renumber[regno] < 0);

  /* Determine the range of registers that must be invalidated.  For
     pseudos, only REGNO is affected.  For hard regs, we must take MODE
     into account, and we must also invalidate lower register numbers
     if they contain values that overlap REGNO.  */
  if (regno < FIRST_PSEUDO_REGISTER)
    {
      gcc_assert (mode != VOIDmode);

      if (regno < max_value_regs)
	i = 0;
      else
	i = regno - max_value_regs;

      endregno = end_hard_regno (mode, regno);
    }
  else
    {
      i = regno;
      endregno = regno + 1;
    }

  for (; i < endregno; i++)
    {
      struct elt_list **l = &REG_VALUES (i);

      /* Go through all known values for this reg; if it overlaps the range
	 we're invalidating, remove the value.  */
      while (*l)
	{
	  cselib_val *v = (*l)->elt;
	  bool had_locs;
	  rtx_insn *setting_insn;
	  struct elt_loc_list **p;
	  unsigned int this_last = i;

	  if (i < FIRST_PSEUDO_REGISTER && v != NULL)
	    this_last = end_hard_regno (GET_MODE (v->val_rtx), i) - 1;

	  if (this_last < regno || v == NULL
	      || (v == cfa_base_preserved_val
		  && i == cfa_base_preserved_regno))
	    {
	      l = &(*l)->next;
	      continue;
	    }

	  /* We have an overlap.  */
	  if (*l == REG_VALUES (i))
	    {
	      /* Maintain the invariant that the first entry of
		 REG_VALUES, if present, must be the value used to set
		 the register, or NULL.  This is also nice because
		 then we won't push the same regno onto user_regs
		 multiple times.  */
	      (*l)->elt = NULL;
	      l = &(*l)->next;
	    }
	  else
	    unchain_one_elt_list (l);

	  v = canonical_cselib_val (v);

	  had_locs = v->locs != NULL;
	  setting_insn = v->locs ? v->locs->setting_insn : NULL;

	  /* Now, we clear the mapping from value to reg.  It must exist, so
	     this code will crash intentionally if it doesn't.  */
	  for (p = &v->locs; ; p = &(*p)->next)
	    {
	      rtx x = (*p)->loc;

	      if (REG_P (x) && REGNO (x) == i)
		{
		  unchain_one_elt_loc_list (p);
		  break;
		}
	    }

	  if (had_locs && v->locs == 0 && !PRESERVED_VALUE_P (v->val_rtx))
	    {
	      if (setting_insn && DEBUG_INSN_P (setting_insn))
		n_useless_debug_values++;
	      else
		n_useless_values++;
	    }
	}
    }
}

/* Invalidate any locations in the table which are changed because of a
   store to MEM_RTX.  If this is called because of a non-const call
   instruction, MEM_RTX is (mem:BLK const0_rtx).  */

static void
cselib_invalidate_mem (rtx mem_rtx)
{
  cselib_val **vp, *v, *next;
  int num_mems = 0;
  rtx mem_addr;

  mem_addr = canon_rtx (get_addr (XEXP (mem_rtx, 0)));
  mem_rtx = canon_rtx (mem_rtx);

  vp = &first_containing_mem;
  for (v = *vp; v != &dummy_val; v = next)
    {
      bool has_mem = false;
      struct elt_loc_list **p = &v->locs;
      bool had_locs = v->locs != NULL;
      rtx_insn *setting_insn = v->locs ? v->locs->setting_insn : NULL;

      while (*p)
	{
	  rtx x = (*p)->loc;
	  cselib_val *addr;
	  struct elt_list **mem_chain;

	  /* MEMs may occur in locations only at the top level; below
	     that every MEM or REG is substituted by its VALUE.  */
	  if (!MEM_P (x))
	    {
	      p = &(*p)->next;
	      continue;
	    }
	  if (num_mems < PARAM_VALUE (PARAM_MAX_CSELIB_MEMORY_LOCATIONS)
	      && ! canon_anti_dependence (x, false, mem_rtx,
					  GET_MODE (mem_rtx), mem_addr))
	    {
	      has_mem = true;
	      num_mems++;
	      p = &(*p)->next;
	      continue;
	    }

	  /* This one overlaps.  */
	  /* We must have a mapping from this MEM's address to the
	     value (E).  Remove that, too.  */
	  addr = cselib_lookup (XEXP (x, 0), VOIDmode, 0, GET_MODE (x));
	  addr = canonical_cselib_val (addr);
	  gcc_checking_assert (v == canonical_cselib_val (v));
	  mem_chain = &addr->addr_list;
	  for (;;)
	    {
	      cselib_val *canon = canonical_cselib_val ((*mem_chain)->elt);

	      if (canon == v)
		{
		  unchain_one_elt_list (mem_chain);
		  break;
		}

	      /* Record canonicalized elt.  */
	      (*mem_chain)->elt = canon;

	      mem_chain = &(*mem_chain)->next;
	    }

	  unchain_one_elt_loc_list (p);
	}

      if (had_locs && v->locs == 0 && !PRESERVED_VALUE_P (v->val_rtx))
	{
	  if (setting_insn && DEBUG_INSN_P (setting_insn))
	    n_useless_debug_values++;
	  else
	    n_useless_values++;
	}

      next = v->next_containing_mem;
      if (has_mem)
	{
	  *vp = v;
	  vp = &(*vp)->next_containing_mem;
	}
      else
	v->next_containing_mem = NULL;
    }
  *vp = &dummy_val;
}

/* Invalidate DEST, which is being assigned to or clobbered.  */

void
cselib_invalidate_rtx (rtx dest)
{
  while (GET_CODE (dest) == SUBREG
	 || GET_CODE (dest) == ZERO_EXTRACT
	 || GET_CODE (dest) == STRICT_LOW_PART)
    dest = XEXP (dest, 0);

  if (REG_P (dest))
    cselib_invalidate_regno (REGNO (dest), GET_MODE (dest));
  else if (MEM_P (dest))
    cselib_invalidate_mem (dest);
}

/* A wrapper for cselib_invalidate_rtx to be called via note_stores.  */

static void
cselib_invalidate_rtx_note_stores (rtx dest, const_rtx ignore ATTRIBUTE_UNUSED,
				   void *data ATTRIBUTE_UNUSED)
{
  cselib_invalidate_rtx (dest);
}

/* Record the result of a SET instruction.  DEST is being set; the source
   contains the value described by SRC_ELT.  If DEST is a MEM, DEST_ADDR_ELT
   describes its address.  */

static void
cselib_record_set (rtx dest, cselib_val *src_elt, cselib_val *dest_addr_elt)
{
  if (src_elt == 0 || side_effects_p (dest))
    return;

  if (REG_P (dest))
    {
      unsigned int dreg = REGNO (dest);
      if (dreg < FIRST_PSEUDO_REGISTER)
	{
	  unsigned int n = REG_NREGS (dest);

	  if (n > max_value_regs)
	    max_value_regs = n;
	}

      if (REG_VALUES (dreg) == 0)
	{
	  used_regs[n_used_regs++] = dreg;
	  REG_VALUES (dreg) = new_elt_list (REG_VALUES (dreg), src_elt);
	}
      else
	{
	  /* The register should have been invalidated.  */
	  gcc_assert (REG_VALUES (dreg)->elt == 0);
	  REG_VALUES (dreg)->elt = src_elt;
	}

      if (src_elt->locs == 0 && !PRESERVED_VALUE_P (src_elt->val_rtx))
	n_useless_values--;
      new_elt_loc_list (src_elt, dest);
    }
  else if (MEM_P (dest) && dest_addr_elt != 0
	   && cselib_record_memory)
    {
      if (src_elt->locs == 0 && !PRESERVED_VALUE_P (src_elt->val_rtx))
	n_useless_values--;
      add_mem_for_addr (dest_addr_elt, src_elt, dest);
    }
}

/* Make ELT and X's VALUE equivalent to each other at INSN.  */

void
cselib_add_permanent_equiv (cselib_val *elt, rtx x, rtx_insn *insn)
{
  cselib_val *nelt;
  rtx_insn *save_cselib_current_insn = cselib_current_insn;

  gcc_checking_assert (elt);
  gcc_checking_assert (PRESERVED_VALUE_P (elt->val_rtx));
  gcc_checking_assert (!side_effects_p (x));

  cselib_current_insn = insn;

  nelt = cselib_lookup (x, GET_MODE (elt->val_rtx), 1, VOIDmode);

  if (nelt != elt)
    {
      cselib_any_perm_equivs = true;

      if (!PRESERVED_VALUE_P (nelt->val_rtx))
	cselib_preserve_value (nelt);

      new_elt_loc_list (nelt, elt->val_rtx);
    }

  cselib_current_insn = save_cselib_current_insn;
}

/* Return TRUE if any permanent equivalences have been recorded since
   the table was last initialized.  */
bool
cselib_have_permanent_equivalences (void)
{
  return cselib_any_perm_equivs;
}

/* There is no good way to determine how many elements there can be
   in a PARALLEL.  Since it's fairly cheap, use a really large number.  */
#define MAX_SETS (FIRST_PSEUDO_REGISTER * 2)

struct cselib_record_autoinc_data
{
  struct cselib_set *sets;
  int n_sets;
};

/* Callback for for_each_inc_dec.  Records in ARG the SETs implied by
   autoinc RTXs: SRC plus SRCOFF if non-NULL is stored in DEST.  */

static int
cselib_record_autoinc_cb (rtx mem ATTRIBUTE_UNUSED, rtx op ATTRIBUTE_UNUSED,
			  rtx dest, rtx src, rtx srcoff, void *arg)
{
  struct cselib_record_autoinc_data *data;
  data = (struct cselib_record_autoinc_data *)arg;

  data->sets[data->n_sets].dest = dest;

  if (srcoff)
    data->sets[data->n_sets].src = gen_rtx_PLUS (GET_MODE (src), src, srcoff);
  else
    data->sets[data->n_sets].src = src;

  data->n_sets++;

  return 0;
}

/* Record the effects of any sets and autoincs in INSN.  */
static void
cselib_record_sets (rtx_insn *insn)
{
  int n_sets = 0;
  int i;
  struct cselib_set sets[MAX_SETS];
  rtx body = PATTERN (insn);
  rtx cond = 0;
  int n_sets_before_autoinc;
  int n_strict_low_parts = 0;
  struct cselib_record_autoinc_data data;

  body = PATTERN (insn);
  if (GET_CODE (body) == COND_EXEC)
    {
      cond = COND_EXEC_TEST (body);
      body = COND_EXEC_CODE (body);
    }

  /* Find all sets.  */
  if (GET_CODE (body) == SET)
    {
      sets[0].src = SET_SRC (body);
      sets[0].dest = SET_DEST (body);
      n_sets = 1;
    }
  else if (GET_CODE (body) == PARALLEL)
    {
      /* Look through the PARALLEL and record the values being
	 set, if possible.  Also handle any CLOBBERs.  */
      for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
	{
	  rtx x = XVECEXP (body, 0, i);

	  if (GET_CODE (x) == SET)
	    {
	      sets[n_sets].src = SET_SRC (x);
	      sets[n_sets].dest = SET_DEST (x);
	      n_sets++;
	    }
	}
    }

  if (n_sets == 1
      && MEM_P (sets[0].src)
      && !cselib_record_memory
      && MEM_READONLY_P (sets[0].src))
    {
      rtx note = find_reg_equal_equiv_note (insn);

      if (note && CONSTANT_P (XEXP (note, 0)))
	sets[0].src = XEXP (note, 0);
    }

  data.sets = sets;
  data.n_sets = n_sets_before_autoinc = n_sets;
  for_each_inc_dec (PATTERN (insn), cselib_record_autoinc_cb, &data);
  n_sets = data.n_sets;

  /* Look up the values that are read.  Do this before invalidating the
     locations that are written.  */
  for (i = 0; i < n_sets; i++)
    {
      rtx dest = sets[i].dest;
      rtx orig = dest;

      /* A STRICT_LOW_PART can be ignored; we'll record the equivalence for
         the low part after invalidating any knowledge about larger modes.  */
      if (GET_CODE (sets[i].dest) == STRICT_LOW_PART)
	sets[i].dest = dest = XEXP (dest, 0);

      /* We don't know how to record anything but REG or MEM.  */
      if (REG_P (dest)
	  || (MEM_P (dest) && cselib_record_memory))
        {
	  rtx src = sets[i].src;
	  if (cond)
	    src = gen_rtx_IF_THEN_ELSE (GET_MODE (dest), cond, src, dest);
	  sets[i].src_elt = cselib_lookup (src, GET_MODE (dest), 1, VOIDmode);
	  if (MEM_P (dest))
	    {
	      machine_mode address_mode = get_address_mode (dest);

	      sets[i].dest_addr_elt = cselib_lookup (XEXP (dest, 0),
						     address_mode, 1,
						     GET_MODE (dest));
	    }
	  else
	    sets[i].dest_addr_elt = 0;
	}

      /* Improve handling of STRICT_LOW_PART if the current value is known
	 to be const0_rtx, then the low bits will be set to dest and higher
	 bits will remain zero.  Used in code like:

	 {di:SI=0;clobber flags:CC;}
	 flags:CCNO=cmp(bx:SI,0)
	 strict_low_part(di:QI)=flags:CCNO<=0

	 where we can note both that di:QI=flags:CCNO<=0 and
	 also that because di:SI is known to be 0 and strict_low_part(di:QI)
	 preserves the upper bits that di:SI=zero_extend(flags:CCNO<=0).  */
      scalar_int_mode mode;
      if (dest != orig
	  && cselib_record_sets_hook
	  && REG_P (dest)
	  && HARD_REGISTER_P (dest)
	  && is_a <scalar_int_mode> (GET_MODE (dest), &mode)
	  && n_sets + n_strict_low_parts < MAX_SETS)
	{
	  opt_scalar_int_mode wider_mode_iter;
	  FOR_EACH_WIDER_MODE (wider_mode_iter, mode)
	    {
	      scalar_int_mode wider_mode = wider_mode_iter.require ();
	      if (GET_MODE_PRECISION (wider_mode) > BITS_PER_WORD)
		break;

	      rtx reg = gen_lowpart (wider_mode, dest);
	      if (!REG_P (reg))
		break;

	      cselib_val *v = cselib_lookup (reg, wider_mode, 0, VOIDmode);
	      if (!v)
		continue;

	      struct elt_loc_list *l;
	      for (l = v->locs; l; l = l->next)
		if (l->loc == const0_rtx)
		  break;

	      if (!l)
		continue;

	      sets[n_sets + n_strict_low_parts].dest = reg;
	      sets[n_sets + n_strict_low_parts].src = dest;
	      sets[n_sets + n_strict_low_parts++].src_elt = sets[i].src_elt;
	      break;
	    }
	}
    }

  if (cselib_record_sets_hook)
    cselib_record_sets_hook (insn, sets, n_sets);

  /* Invalidate all locations written by this insn.  Note that the elts we
     looked up in the previous loop aren't affected, just some of their
     locations may go away.  */
  note_stores (body, cselib_invalidate_rtx_note_stores, NULL);

  for (i = n_sets_before_autoinc; i < n_sets; i++)
    cselib_invalidate_rtx (sets[i].dest);

  /* If this is an asm, look for duplicate sets.  This can happen when the
     user uses the same value as an output multiple times.  This is valid
     if the outputs are not actually used thereafter.  Treat this case as
     if the value isn't actually set.  We do this by smashing the destination
     to pc_rtx, so that we won't record the value later.  */
  if (n_sets >= 2 && asm_noperands (body) >= 0)
    {
      for (i = 0; i < n_sets; i++)
	{
	  rtx dest = sets[i].dest;
	  if (REG_P (dest) || MEM_P (dest))
	    {
	      int j;
	      for (j = i + 1; j < n_sets; j++)
		if (rtx_equal_p (dest, sets[j].dest))
		  {
		    sets[i].dest = pc_rtx;
		    sets[j].dest = pc_rtx;
		  }
	    }
	}
    }

  /* Now enter the equivalences in our tables.  */
  for (i = 0; i < n_sets; i++)
    {
      rtx dest = sets[i].dest;
      if (REG_P (dest)
	  || (MEM_P (dest) && cselib_record_memory))
	cselib_record_set (dest, sets[i].src_elt, sets[i].dest_addr_elt);
    }

  /* And deal with STRICT_LOW_PART.  */
  for (i = 0; i < n_strict_low_parts; i++)
    {
      if (! PRESERVED_VALUE_P (sets[n_sets + i].src_elt->val_rtx))
	continue;
      machine_mode dest_mode = GET_MODE (sets[n_sets + i].dest);
      cselib_val *v
	= cselib_lookup (sets[n_sets + i].dest, dest_mode, 1, VOIDmode);
      cselib_preserve_value (v);
      rtx r = gen_rtx_ZERO_EXTEND (dest_mode,
				   sets[n_sets + i].src_elt->val_rtx);
      cselib_add_permanent_equiv (v, r, insn);
    }
}

/* Return true if INSN in the prologue initializes hard_frame_pointer_rtx.  */

bool
fp_setter_insn (rtx_insn *insn)
{
  rtx expr, pat = NULL_RTX;

  if (!RTX_FRAME_RELATED_P (insn))
    return false;

  expr = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX);
  if (expr)
    pat = XEXP (expr, 0);
  if (!modified_in_p (hard_frame_pointer_rtx, pat ? pat : insn))
    return false;

  /* Don't return true for frame pointer restores in the epilogue.  */
  if (find_reg_note (insn, REG_CFA_RESTORE, hard_frame_pointer_rtx))
    return false;
  return true;
}

/* Record the effects of INSN.  */

void
cselib_process_insn (rtx_insn *insn)
{
  int i;
  rtx x;

  cselib_current_insn = insn;

  /* Forget everything at a CODE_LABEL or a setjmp.  */
  if ((LABEL_P (insn)
       || (CALL_P (insn)
	   && find_reg_note (insn, REG_SETJMP, NULL)))
      && !cselib_preserve_constants)
    {
      cselib_reset_table (next_uid);
      cselib_current_insn = NULL;
      return;
    }

  if (! INSN_P (insn))
    {
      cselib_current_insn = NULL;
      return;
    }

  /* If this is a call instruction, forget anything stored in a
     call clobbered register, or, if this is not a const call, in
     memory.  */
  if (CALL_P (insn))
    {
      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
	if (call_used_regs[i]
	    || (REG_VALUES (i) && REG_VALUES (i)->elt
		&& (targetm.hard_regno_call_part_clobbered
		    (i, GET_MODE (REG_VALUES (i)->elt->val_rtx)))))
	  cselib_invalidate_regno (i, reg_raw_mode[i]);

      /* Since it is not clear how cselib is going to be used, be
	 conservative here and treat looping pure or const functions
	 as if they were regular functions.  */
      if (RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)
	  || !(RTL_CONST_OR_PURE_CALL_P (insn)))
	cselib_invalidate_mem (callmem);
      else
	/* For const/pure calls, invalidate any argument slots because
	   they are owned by the callee.  */
	for (x = CALL_INSN_FUNCTION_USAGE (insn); x; x = XEXP (x, 1))
	  if (GET_CODE (XEXP (x, 0)) == USE
	      && MEM_P (XEXP (XEXP (x, 0), 0)))
	    cselib_invalidate_mem (XEXP (XEXP (x, 0), 0));
    }

  cselib_record_sets (insn);

  /* Look for any CLOBBERs in CALL_INSN_FUNCTION_USAGE, but only
     after we have processed the insn.  */
  if (CALL_P (insn))
    {
      for (x = CALL_INSN_FUNCTION_USAGE (insn); x; x = XEXP (x, 1))
	if (GET_CODE (XEXP (x, 0)) == CLOBBER)
	  cselib_invalidate_rtx (XEXP (XEXP (x, 0), 0));
      /* Flush evertything on setjmp.  */
      if (cselib_preserve_constants
	  && find_reg_note (insn, REG_SETJMP, NULL))
	{
	  cselib_preserve_only_values ();
	  cselib_reset_table (next_uid);
	}
    }

  /* On setter of the hard frame pointer if frame_pointer_needed,
     invalidate stack_pointer_rtx, so that sp and {,h}fp based
     VALUEs are distinct.  */
  if (reload_completed
      && frame_pointer_needed
      && fp_setter_insn (insn))
    cselib_invalidate_rtx (stack_pointer_rtx);

  cselib_current_insn = NULL;

  if (n_useless_values > MAX_USELESS_VALUES
      /* remove_useless_values is linear in the hash table size.  Avoid
         quadratic behavior for very large hashtables with very few
	 useless elements.  */
      && ((unsigned int)n_useless_values
	  > (cselib_hash_table->elements () - n_debug_values) / 4))
    remove_useless_values ();
}

/* Initialize cselib for one pass.  The caller must also call
   init_alias_analysis.  */

void
cselib_init (int record_what)
{
  cselib_record_memory = record_what & CSELIB_RECORD_MEMORY;
  cselib_preserve_constants = record_what & CSELIB_PRESERVE_CONSTANTS;
  cselib_any_perm_equivs = false;

  /* (mem:BLK (scratch)) is a special mechanism to conflict with everything,
     see canon_true_dependence.  This is only created once.  */
  if (! callmem)
    callmem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode));

  cselib_nregs = max_reg_num ();

  /* We preserve reg_values to allow expensive clearing of the whole thing.
     Reallocate it however if it happens to be too large.  */
  if (!reg_values || reg_values_size < cselib_nregs
      || (reg_values_size > 10 && reg_values_size > cselib_nregs * 4))
    {
      free (reg_values);
      /* Some space for newly emit instructions so we don't end up
	 reallocating in between passes.  */
      reg_values_size = cselib_nregs + (63 + cselib_nregs) / 16;
      reg_values = XCNEWVEC (struct elt_list *, reg_values_size);
    }
  used_regs = XNEWVEC (unsigned int, cselib_nregs);
  n_used_regs = 0;
  cselib_hash_table = new hash_table<cselib_hasher> (31);
  if (cselib_preserve_constants)
    cselib_preserved_hash_table = new hash_table<cselib_hasher> (31);
  next_uid = 1;
}

/* Called when the current user is done with cselib.  */

void
cselib_finish (void)
{
  bool preserved = cselib_preserve_constants;
  cselib_discard_hook = NULL;
  cselib_preserve_constants = false;
  cselib_any_perm_equivs = false;
  cfa_base_preserved_val = NULL;
  cfa_base_preserved_regno = INVALID_REGNUM;
  elt_list_pool.release ();
  elt_loc_list_pool.release ();
  cselib_val_pool.release ();
  value_pool.release ();
  cselib_clear_table ();
  delete cselib_hash_table;
  cselib_hash_table = NULL;
  if (preserved)
    delete cselib_preserved_hash_table;
  cselib_preserved_hash_table = NULL;
  free (used_regs);
  used_regs = 0;
  n_useless_values = 0;
  n_useless_debug_values = 0;
  n_debug_values = 0;
  next_uid = 0;
}

/* Dump the cselib_val *X to FILE *OUT.  */

int
dump_cselib_val (cselib_val **x, FILE *out)
{
  cselib_val *v = *x;
  bool need_lf = true;

  print_inline_rtx (out, v->val_rtx, 0);

  if (v->locs)
    {
      struct elt_loc_list *l = v->locs;
      if (need_lf)
	{
	  fputc ('\n', out);
	  need_lf = false;
	}
      fputs (" locs:", out);
      do
	{
	  if (l->setting_insn)
	    fprintf (out, "\n  from insn %i ",
		     INSN_UID (l->setting_insn));
	  else
	    fprintf (out, "\n   ");
	  print_inline_rtx (out, l->loc, 4);
	}
      while ((l = l->next));
      fputc ('\n', out);
    }
  else
    {
      fputs (" no locs", out);
      need_lf = true;
    }

  if (v->addr_list)
    {
      struct elt_list *e = v->addr_list;
      if (need_lf)
	{
	  fputc ('\n', out);
	  need_lf = false;
	}
      fputs (" addr list:", out);
      do
	{
	  fputs ("\n  ", out);
	  print_inline_rtx (out, e->elt->val_rtx, 2);
	}
      while ((e = e->next));
      fputc ('\n', out);
    }
  else
    {
      fputs (" no addrs", out);
      need_lf = true;
    }

  if (v->next_containing_mem == &dummy_val)
    fputs (" last mem\n", out);
  else if (v->next_containing_mem)
    {
      fputs (" next mem ", out);
      print_inline_rtx (out, v->next_containing_mem->val_rtx, 2);
      fputc ('\n', out);
    }
  else if (need_lf)
    fputc ('\n', out);

  return 1;
}

/* Dump to OUT everything in the CSELIB table.  */

void
dump_cselib_table (FILE *out)
{
  fprintf (out, "cselib hash table:\n");
  cselib_hash_table->traverse <FILE *, dump_cselib_val> (out);
  fprintf (out, "cselib preserved hash table:\n");
  cselib_preserved_hash_table->traverse <FILE *, dump_cselib_val> (out);
  if (first_containing_mem != &dummy_val)
    {
      fputs ("first mem ", out);
      print_inline_rtx (out, first_containing_mem->val_rtx, 2);
      fputc ('\n', out);
    }
  fprintf (out, "next uid %i\n", next_uid);
}

#include "gt-cselib.h"
