/* Variable tracking routines for the GNU compiler.
   Copyright (C) 2002-2022 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/>.  */

/* This file contains the variable tracking pass.  It computes where
   variables are located (which registers or where in memory) at each position
   in instruction stream and emits notes describing the locations.
   Debug information (DWARF2 location lists) is finally generated from
   these notes.
   With this debug information, it is possible to show variables
   even when debugging optimized code.

   How does the variable tracking pass work?

   First, it scans RTL code for uses, stores and clobbers (register/memory
   references in instructions), for call insns and for stack adjustments
   separately for each basic block and saves them to an array of micro
   operations.
   The micro operations of one instruction are ordered so that
   pre-modifying stack adjustment < use < use with no var < call insn <
     < clobber < set < post-modifying stack adjustment

   Then, a forward dataflow analysis is performed to find out how locations
   of variables change through code and to propagate the variable locations
   along control flow graph.
   The IN set for basic block BB is computed as a union of OUT sets of BB's
   predecessors, the OUT set for BB is copied from the IN set for BB and
   is changed according to micro operations in BB.

   The IN and OUT sets for basic blocks consist of a current stack adjustment
   (used for adjusting offset of variables addressed using stack pointer),
   the table of structures describing the locations of parts of a variable
   and for each physical register a linked list for each physical register.
   The linked list is a list of variable parts stored in the register,
   i.e. it is a list of triplets (reg, decl, offset) where decl is
   REG_EXPR (reg) and offset is REG_OFFSET (reg).  The linked list is used for
   effective deleting appropriate variable parts when we set or clobber the
   register.

   There may be more than one variable part in a register.  The linked lists
   should be pretty short so it is a good data structure here.
   For example in the following code, register allocator may assign same
   register to variables A and B, and both of them are stored in the same
   register in CODE:

     if (cond)
       set A;
     else
       set B;
     CODE;
     if (cond)
       use A;
     else
       use B;

   Finally, the NOTE_INSN_VAR_LOCATION notes describing the variable locations
   are emitted to appropriate positions in RTL code.  Each such a note describes
   the location of one variable at the point in instruction stream where the
   note is.  There is no need to emit a note for each variable before each
   instruction, we only emit these notes where the location of variable changes
   (this means that we also emit notes for changes between the OUT set of the
   previous block and the IN set of the current block).

   The notes consist of two parts:
   1. the declaration (from REG_EXPR or MEM_EXPR)
   2. the location of a variable - it is either a simple register/memory
      reference (for simple variables, for example int),
      or a parallel of register/memory references (for a large variables
      which consist of several parts, for example long long).

*/

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "cfghooks.h"
#include "alloc-pool.h"
#include "tree-pass.h"
#include "memmodel.h"
#include "tm_p.h"
#include "insn-config.h"
#include "regs.h"
#include "emit-rtl.h"
#include "recog.h"
#include "diagnostic.h"
#include "varasm.h"
#include "stor-layout.h"
#include "cfgrtl.h"
#include "cfganal.h"
#include "reload.h"
#include "calls.h"
#include "tree-dfa.h"
#include "tree-ssa.h"
#include "cselib.h"
#include "tree-pretty-print.h"
#include "rtl-iter.h"
#include "fibonacci_heap.h"
#include "print-rtl.h"
#include "function-abi.h"

typedef fibonacci_heap <long, basic_block_def> bb_heap_t;

/* var-tracking.cc assumes that tree code with the same value as VALUE rtx code
   has no chance to appear in REG_EXPR/MEM_EXPRs and isn't a decl.
   Currently the value is the same as IDENTIFIER_NODE, which has such
   a property.  If this compile time assertion ever fails, make sure that
   the new tree code that equals (int) VALUE has the same property.  */
extern char check_value_val[(int) VALUE == (int) IDENTIFIER_NODE ? 1 : -1];

/* Type of micro operation.  */
enum micro_operation_type
{
  MO_USE,	/* Use location (REG or MEM).  */
  MO_USE_NO_VAR,/* Use location which is not associated with a variable
		   or the variable is not trackable.  */
  MO_VAL_USE,	/* Use location which is associated with a value.  */
  MO_VAL_LOC,   /* Use location which appears in a debug insn.  */
  MO_VAL_SET,	/* Set location associated with a value.  */
  MO_SET,	/* Set location.  */
  MO_COPY,	/* Copy the same portion of a variable from one
		   location to another.  */
  MO_CLOBBER,	/* Clobber location.  */
  MO_CALL,	/* Call insn.  */
  MO_ADJUST	/* Adjust stack pointer.  */

};

static const char * const ATTRIBUTE_UNUSED
micro_operation_type_name[] = {
  "MO_USE",
  "MO_USE_NO_VAR",
  "MO_VAL_USE",
  "MO_VAL_LOC",
  "MO_VAL_SET",
  "MO_SET",
  "MO_COPY",
  "MO_CLOBBER",
  "MO_CALL",
  "MO_ADJUST"
};

/* Where shall the note be emitted?  BEFORE or AFTER the instruction.
   Notes emitted as AFTER_CALL are to take effect during the call,
   rather than after the call.  */
enum emit_note_where
{
  EMIT_NOTE_BEFORE_INSN,
  EMIT_NOTE_AFTER_INSN,
  EMIT_NOTE_AFTER_CALL_INSN
};

/* Structure holding information about micro operation.  */
struct micro_operation
{
  /* Type of micro operation.  */
  enum micro_operation_type type;

  /* The instruction which the micro operation is in, for MO_USE,
     MO_USE_NO_VAR, MO_CALL and MO_ADJUST, or the subsequent
     instruction or note in the original flow (before any var-tracking
     notes are inserted, to simplify emission of notes), for MO_SET
     and MO_CLOBBER.  */
  rtx_insn *insn;

  union {
    /* Location.  For MO_SET and MO_COPY, this is the SET that
       performs the assignment, if known, otherwise it is the target
       of the assignment.  For MO_VAL_USE and MO_VAL_SET, it is a
       CONCAT of the VALUE and the LOC associated with it.  For
       MO_VAL_LOC, it is a CONCAT of the VALUE and the VAR_LOCATION
       associated with it.  */
    rtx loc;

    /* Stack adjustment.  */
    HOST_WIDE_INT adjust;
  } u;
};


/* A declaration of a variable, or an RTL value being handled like a
   declaration.  */
typedef void *decl_or_value;

/* Return true if a decl_or_value DV is a DECL or NULL.  */
static inline bool
dv_is_decl_p (decl_or_value dv)
{
  return !dv || (int) TREE_CODE ((tree) dv) != (int) VALUE;
}

/* Return true if a decl_or_value is a VALUE rtl.  */
static inline bool
dv_is_value_p (decl_or_value dv)
{
  return dv && !dv_is_decl_p (dv);
}

/* Return the decl in the decl_or_value.  */
static inline tree
dv_as_decl (decl_or_value dv)
{
  gcc_checking_assert (dv_is_decl_p (dv));
  return (tree) dv;
}

/* Return the value in the decl_or_value.  */
static inline rtx
dv_as_value (decl_or_value dv)
{
  gcc_checking_assert (dv_is_value_p (dv));
  return (rtx)dv;
}

/* Return the opaque pointer in the decl_or_value.  */
static inline void *
dv_as_opaque (decl_or_value dv)
{
  return dv;
}


/* Description of location of a part of a variable.  The content of a physical
   register is described by a chain of these structures.
   The chains are pretty short (usually 1 or 2 elements) and thus
   chain is the best data structure.  */
struct attrs
{
  /* Pointer to next member of the list.  */
  attrs *next;

  /* The rtx of register.  */
  rtx loc;

  /* The declaration corresponding to LOC.  */
  decl_or_value dv;

  /* Offset from start of DECL.  */
  HOST_WIDE_INT offset;
};

/* Structure for chaining the locations.  */
struct location_chain
{
  /* Next element in the chain.  */
  location_chain *next;

  /* The location (REG, MEM or VALUE).  */
  rtx loc;

  /* The "value" stored in this location.  */
  rtx set_src;

  /* Initialized? */
  enum var_init_status init;
};

/* A vector of loc_exp_dep holds the active dependencies of a one-part
   DV on VALUEs, i.e., the VALUEs expanded so as to form the current
   location of DV.  Each entry is also part of VALUE' s linked-list of
   backlinks back to DV.  */
struct loc_exp_dep
{
  /* The dependent DV.  */
  decl_or_value dv;
  /* The dependency VALUE or DECL_DEBUG.  */
  rtx value;
  /* The next entry in VALUE's backlinks list.  */
  struct loc_exp_dep *next;
  /* A pointer to the pointer to this entry (head or prev's next) in
     the doubly-linked list.  */
  struct loc_exp_dep **pprev;
};


/* This data structure holds information about the depth of a variable
   expansion.  */
struct expand_depth
{
  /* This measures the complexity of the expanded expression.  It
     grows by one for each level of expansion that adds more than one
     operand.  */
  int complexity;
  /* This counts the number of ENTRY_VALUE expressions in an
     expansion.  We want to minimize their use.  */
  int entryvals;
};

/* Type for dependencies actively used when expand FROM into cur_loc.  */
typedef vec<loc_exp_dep, va_heap, vl_embed> deps_vec;

/* This data structure is allocated for one-part variables at the time
   of emitting notes.  */
struct onepart_aux
{
  /* Doubly-linked list of dependent DVs.  These are DVs whose cur_loc
     computation used the expansion of this variable, and that ought
     to be notified should this variable change.  If the DV's cur_loc
     expanded to NULL, all components of the loc list are regarded as
     active, so that any changes in them give us a chance to get a
     location.  Otherwise, only components of the loc that expanded to
     non-NULL are regarded as active dependencies.  */
  loc_exp_dep *backlinks;
  /* This holds the LOC that was expanded into cur_loc.  We need only
     mark a one-part variable as changed if the FROM loc is removed,
     or if it has no known location and a loc is added, or if it gets
     a change notification from any of its active dependencies.  */
  rtx from;
  /* The depth of the cur_loc expression.  */
  expand_depth depth;
  /* Dependencies actively used when expand FROM into cur_loc.  */
  deps_vec deps;
};

/* Structure describing one part of variable.  */
struct variable_part
{
  /* Chain of locations of the part.  */
  location_chain *loc_chain;

  /* Location which was last emitted to location list.  */
  rtx cur_loc;

  union variable_aux
  {
    /* The offset in the variable, if !var->onepart.  */
    HOST_WIDE_INT offset;

    /* Pointer to auxiliary data, if var->onepart and emit_notes.  */
    struct onepart_aux *onepaux;
  } aux;
};

/* Maximum number of location parts.  */
#define MAX_VAR_PARTS 16

/* Enumeration type used to discriminate various types of one-part
   variables.  */
enum onepart_enum
{
  /* Not a one-part variable.  */
  NOT_ONEPART = 0,
  /* A one-part DECL that is not a DEBUG_EXPR_DECL.  */
  ONEPART_VDECL = 1,
  /* A DEBUG_EXPR_DECL.  */
  ONEPART_DEXPR = 2,
  /* A VALUE.  */
  ONEPART_VALUE = 3
};

/* Structure describing where the variable is located.  */
struct variable
{
  /* The declaration of the variable, or an RTL value being handled
     like a declaration.  */
  decl_or_value dv;

  /* Reference count.  */
  int refcount;

  /* Number of variable parts.  */
  char n_var_parts;

  /* What type of DV this is, according to enum onepart_enum.  */
  ENUM_BITFIELD (onepart_enum) onepart : CHAR_BIT;

  /* True if this variable_def struct is currently in the
     changed_variables hash table.  */
  bool in_changed_variables;

  /* The variable parts.  */
  variable_part var_part[1];
};

/* Pointer to the BB's information specific to variable tracking pass.  */
#define VTI(BB) ((variable_tracking_info *) (BB)->aux)

/* Return MEM_OFFSET (MEM) as a HOST_WIDE_INT, or 0 if we can't.  */

static inline HOST_WIDE_INT
int_mem_offset (const_rtx mem)
{
  HOST_WIDE_INT offset;
  if (MEM_OFFSET_KNOWN_P (mem) && MEM_OFFSET (mem).is_constant (&offset))
    return offset;
  return 0;
}

#if CHECKING_P && (GCC_VERSION >= 2007)

/* Access VAR's Ith part's offset, checking that it's not a one-part
   variable.  */
#define VAR_PART_OFFSET(var, i) __extension__			\
(*({  variable *const __v = (var);				\
      gcc_checking_assert (!__v->onepart);			\
      &__v->var_part[(i)].aux.offset; }))

/* Access VAR's one-part auxiliary data, checking that it is a
   one-part variable.  */
#define VAR_LOC_1PAUX(var) __extension__			\
(*({  variable *const __v = (var);				\
      gcc_checking_assert (__v->onepart);			\
      &__v->var_part[0].aux.onepaux; }))

#else
#define VAR_PART_OFFSET(var, i) ((var)->var_part[(i)].aux.offset)
#define VAR_LOC_1PAUX(var) ((var)->var_part[0].aux.onepaux)
#endif

/* These are accessor macros for the one-part auxiliary data.  When
   convenient for users, they're guarded by tests that the data was
   allocated.  */
#define VAR_LOC_DEP_LST(var) (VAR_LOC_1PAUX (var)		  \
			      ? VAR_LOC_1PAUX (var)->backlinks	  \
			      : NULL)
#define VAR_LOC_DEP_LSTP(var) (VAR_LOC_1PAUX (var)		  \
			       ? &VAR_LOC_1PAUX (var)->backlinks  \
			       : NULL)
#define VAR_LOC_FROM(var) (VAR_LOC_1PAUX (var)->from)
#define VAR_LOC_DEPTH(var) (VAR_LOC_1PAUX (var)->depth)
#define VAR_LOC_DEP_VEC(var) var_loc_dep_vec (var)

/* Implements the VAR_LOC_DEP_VEC above as a function to work around
   a bogus -Wnonnull (PR c/95554). */

static inline deps_vec*
var_loc_dep_vec (variable *var)
{
  return VAR_LOC_1PAUX (var) ? &VAR_LOC_1PAUX (var)->deps : NULL;
}


typedef unsigned int dvuid;

/* Return the uid of DV.  */

static inline dvuid
dv_uid (decl_or_value dv)
{
  if (dv_is_value_p (dv))
    return CSELIB_VAL_PTR (dv_as_value (dv))->uid;
  else
    return DECL_UID (dv_as_decl (dv));
}

/* Compute the hash from the uid.  */

static inline hashval_t
dv_uid2hash (dvuid uid)
{
  return uid;
}

/* The hash function for a mask table in a shared_htab chain.  */

static inline hashval_t
dv_htab_hash (decl_or_value dv)
{
  return dv_uid2hash (dv_uid (dv));
}

static void variable_htab_free (void *);

/* Variable hashtable helpers.  */

struct variable_hasher : pointer_hash <variable>
{
  typedef void *compare_type;
  static inline hashval_t hash (const variable *);
  static inline bool equal (const variable *, const void *);
  static inline void remove (variable *);
};

/* The hash function for variable_htab, computes the hash value
   from the declaration of variable X.  */

inline hashval_t
variable_hasher::hash (const variable *v)
{
  return dv_htab_hash (v->dv);
}

/* Compare the declaration of variable X with declaration Y.  */

inline bool
variable_hasher::equal (const variable *v, const void *y)
{
  decl_or_value dv = CONST_CAST2 (decl_or_value, const void *, y);

  return (dv_as_opaque (v->dv) == dv_as_opaque (dv));
}

/* Free the element of VARIABLE_HTAB (its type is struct variable_def).  */

inline void
variable_hasher::remove (variable *var)
{
  variable_htab_free (var);
}

typedef hash_table<variable_hasher> variable_table_type;
typedef variable_table_type::iterator variable_iterator_type;

/* Structure for passing some other parameters to function
   emit_note_insn_var_location.  */
struct emit_note_data
{
  /* The instruction which the note will be emitted before/after.  */
  rtx_insn *insn;

  /* Where the note will be emitted (before/after insn)?  */
  enum emit_note_where where;

  /* The variables and values active at this point.  */
  variable_table_type *vars;
};

/* Structure holding a refcounted hash table.  If refcount > 1,
   it must be first unshared before modified.  */
struct shared_hash
{
  /* Reference count.  */
  int refcount;

  /* Actual hash table.  */
  variable_table_type *htab;
};

/* Structure holding the IN or OUT set for a basic block.  */
struct dataflow_set
{
  /* Adjustment of stack offset.  */
  HOST_WIDE_INT stack_adjust;

  /* Attributes for registers (lists of attrs).  */
  attrs *regs[FIRST_PSEUDO_REGISTER];

  /* Variable locations.  */
  shared_hash *vars;

  /* Vars that is being traversed.  */
  shared_hash *traversed_vars;
};

/* The structure (one for each basic block) containing the information
   needed for variable tracking.  */
struct variable_tracking_info
{
  /* The vector of micro operations.  */
  vec<micro_operation> mos;

  /* The IN and OUT set for dataflow analysis.  */
  dataflow_set in;
  dataflow_set out;

  /* The permanent-in dataflow set for this block.  This is used to
     hold values for which we had to compute entry values.  ??? This
     should probably be dynamically allocated, to avoid using more
     memory in non-debug builds.  */
  dataflow_set *permp;

  /* Has the block been visited in DFS?  */
  bool visited;

  /* Has the block been flooded in VTA?  */
  bool flooded;

};

/* Alloc pool for struct attrs_def.  */
object_allocator<attrs> attrs_pool ("attrs pool");

/* Alloc pool for struct variable_def with MAX_VAR_PARTS entries.  */

static pool_allocator var_pool
  ("variable_def pool", sizeof (variable) +
   (MAX_VAR_PARTS - 1) * sizeof (((variable *)NULL)->var_part[0]));

/* Alloc pool for struct variable_def with a single var_part entry.  */
static pool_allocator valvar_pool
  ("small variable_def pool", sizeof (variable));

/* Alloc pool for struct location_chain.  */
static object_allocator<location_chain> location_chain_pool
  ("location_chain pool");

/* Alloc pool for struct shared_hash.  */
static object_allocator<shared_hash> shared_hash_pool ("shared_hash pool");

/* Alloc pool for struct loc_exp_dep_s for NOT_ONEPART variables.  */
object_allocator<loc_exp_dep> loc_exp_dep_pool ("loc_exp_dep pool");

/* Changed variables, notes will be emitted for them.  */
static variable_table_type *changed_variables;

/* Shall notes be emitted?  */
static bool emit_notes;

/* Values whose dynamic location lists have gone empty, but whose
   cselib location lists are still usable.  Use this to hold the
   current location, the backlinks, etc, during emit_notes.  */
static variable_table_type *dropped_values;

/* Empty shared hashtable.  */
static shared_hash *empty_shared_hash;

/* Scratch register bitmap used by cselib_expand_value_rtx.  */
static bitmap scratch_regs = NULL;

#ifdef HAVE_window_save
struct GTY(()) parm_reg {
  rtx outgoing;
  rtx incoming;
};


/* Vector of windowed parameter registers, if any.  */
static vec<parm_reg, va_gc> *windowed_parm_regs = NULL;
#endif

/* Variable used to tell whether cselib_process_insn called our hook.  */
static bool cselib_hook_called;

/* Local function prototypes.  */
static void stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *,
					  HOST_WIDE_INT *);
static void insn_stack_adjust_offset_pre_post (rtx_insn *, HOST_WIDE_INT *,
					       HOST_WIDE_INT *);
static bool vt_stack_adjustments (void);

static void init_attrs_list_set (attrs **);
static void attrs_list_clear (attrs **);
static attrs *attrs_list_member (attrs *, decl_or_value, HOST_WIDE_INT);
static void attrs_list_insert (attrs **, decl_or_value, HOST_WIDE_INT, rtx);
static void attrs_list_copy (attrs **, attrs *);
static void attrs_list_union (attrs **, attrs *);

static variable **unshare_variable (dataflow_set *set, variable **slot,
					variable *var, enum var_init_status);
static void vars_copy (variable_table_type *, variable_table_type *);
static tree var_debug_decl (tree);
static void var_reg_set (dataflow_set *, rtx, enum var_init_status, rtx);
static void var_reg_delete_and_set (dataflow_set *, rtx, bool,
				    enum var_init_status, rtx);
static void var_reg_delete (dataflow_set *, rtx, bool);
static void var_regno_delete (dataflow_set *, int);
static void var_mem_set (dataflow_set *, rtx, enum var_init_status, rtx);
static void var_mem_delete_and_set (dataflow_set *, rtx, bool,
				    enum var_init_status, rtx);
static void var_mem_delete (dataflow_set *, rtx, bool);

static void dataflow_set_init (dataflow_set *);
static void dataflow_set_clear (dataflow_set *);
static void dataflow_set_copy (dataflow_set *, dataflow_set *);
static int variable_union_info_cmp_pos (const void *, const void *);
static void dataflow_set_union (dataflow_set *, dataflow_set *);
static location_chain *find_loc_in_1pdv (rtx, variable *,
					 variable_table_type *);
static bool canon_value_cmp (rtx, rtx);
static int loc_cmp (rtx, rtx);
static bool variable_part_different_p (variable_part *, variable_part *);
static bool onepart_variable_different_p (variable *, variable *);
static bool variable_different_p (variable *, variable *);
static bool dataflow_set_different (dataflow_set *, dataflow_set *);
static void dataflow_set_destroy (dataflow_set *);

static bool track_expr_p (tree, bool);
static void add_uses_1 (rtx *, void *);
static void add_stores (rtx, const_rtx, void *);
static bool compute_bb_dataflow (basic_block);
static bool vt_find_locations (void);

static void dump_attrs_list (attrs *);
static void dump_var (variable *);
static void dump_vars (variable_table_type *);
static void dump_dataflow_set (dataflow_set *);
static void dump_dataflow_sets (void);

static void set_dv_changed (decl_or_value, bool);
static void variable_was_changed (variable *, dataflow_set *);
static variable **set_slot_part (dataflow_set *, rtx, variable **,
				 decl_or_value, HOST_WIDE_INT,
				 enum var_init_status, rtx);
static void set_variable_part (dataflow_set *, rtx,
			       decl_or_value, HOST_WIDE_INT,
			       enum var_init_status, rtx, enum insert_option);
static variable **clobber_slot_part (dataflow_set *, rtx,
				     variable **, HOST_WIDE_INT, rtx);
static void clobber_variable_part (dataflow_set *, rtx,
				   decl_or_value, HOST_WIDE_INT, rtx);
static variable **delete_slot_part (dataflow_set *, rtx, variable **,
				    HOST_WIDE_INT);
static void delete_variable_part (dataflow_set *, rtx,
				  decl_or_value, HOST_WIDE_INT);
static void emit_notes_in_bb (basic_block, dataflow_set *);
static void vt_emit_notes (void);

static void vt_add_function_parameters (void);
static bool vt_initialize (void);
static void vt_finalize (void);

/* Callback for stack_adjust_offset_pre_post, called via for_each_inc_dec.  */

static int
stack_adjust_offset_pre_post_cb (rtx, rtx op, rtx dest, rtx src, rtx srcoff,
				 void *arg)
{
  if (dest != stack_pointer_rtx)
    return 0;

  switch (GET_CODE (op))
    {
    case PRE_INC:
    case PRE_DEC:
      ((HOST_WIDE_INT *)arg)[0] -= INTVAL (srcoff);
      return 0;
    case POST_INC:
    case POST_DEC:
      ((HOST_WIDE_INT *)arg)[1] -= INTVAL (srcoff);
      return 0;
    case PRE_MODIFY:
    case POST_MODIFY:
      /* We handle only adjustments by constant amount.  */
      gcc_assert (GET_CODE (src) == PLUS
		  && CONST_INT_P (XEXP (src, 1))
		  && XEXP (src, 0) == stack_pointer_rtx);
      ((HOST_WIDE_INT *)arg)[GET_CODE (op) == POST_MODIFY]
	-= INTVAL (XEXP (src, 1));
      return 0;
    default:
      gcc_unreachable ();
    }
}

/* Given a SET, calculate the amount of stack adjustment it contains
   PRE- and POST-modifying stack pointer.
   This function is similar to stack_adjust_offset.  */

static void
stack_adjust_offset_pre_post (rtx pattern, HOST_WIDE_INT *pre,
			      HOST_WIDE_INT *post)
{
  rtx src = SET_SRC (pattern);
  rtx dest = SET_DEST (pattern);
  enum rtx_code code;

  if (dest == stack_pointer_rtx)
    {
      /* (set (reg sp) (plus (reg sp) (const_int))) */
      code = GET_CODE (src);
      if (! (code == PLUS || code == MINUS)
	  || XEXP (src, 0) != stack_pointer_rtx
	  || !CONST_INT_P (XEXP (src, 1)))
	return;

      if (code == MINUS)
	*post += INTVAL (XEXP (src, 1));
      else
	*post -= INTVAL (XEXP (src, 1));
      return;
    }
  HOST_WIDE_INT res[2] = { 0, 0 };
  for_each_inc_dec (pattern, stack_adjust_offset_pre_post_cb, res);
  *pre += res[0];
  *post += res[1];
}

/* Given an INSN, calculate the amount of stack adjustment it contains
   PRE- and POST-modifying stack pointer.  */

static void
insn_stack_adjust_offset_pre_post (rtx_insn *insn, HOST_WIDE_INT *pre,
				   HOST_WIDE_INT *post)
{
  rtx pattern;

  *pre = 0;
  *post = 0;

  pattern = PATTERN (insn);
  if (RTX_FRAME_RELATED_P (insn))
    {
      rtx expr = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX);
      if (expr)
	pattern = XEXP (expr, 0);
    }

  if (GET_CODE (pattern) == SET)
    stack_adjust_offset_pre_post (pattern, pre, post);
  else if (GET_CODE (pattern) == PARALLEL
	   || GET_CODE (pattern) == SEQUENCE)
    {
      int i;

      /* There may be stack adjustments inside compound insns.  Search
	 for them.  */
      for ( i = XVECLEN (pattern, 0) - 1; i >= 0; i--)
	if (GET_CODE (XVECEXP (pattern, 0, i)) == SET)
	  stack_adjust_offset_pre_post (XVECEXP (pattern, 0, i), pre, post);
    }
}

/* Compute stack adjustments for all blocks by traversing DFS tree.
   Return true when the adjustments on all incoming edges are consistent.
   Heavily borrowed from pre_and_rev_post_order_compute.  */

static bool
vt_stack_adjustments (void)
{
  edge_iterator *stack;
  int sp;

  /* Initialize entry block.  */
  VTI (ENTRY_BLOCK_PTR_FOR_FN (cfun))->visited = true;
  VTI (ENTRY_BLOCK_PTR_FOR_FN (cfun))->in.stack_adjust
    = INCOMING_FRAME_SP_OFFSET;
  VTI (ENTRY_BLOCK_PTR_FOR_FN (cfun))->out.stack_adjust
    = INCOMING_FRAME_SP_OFFSET;

  /* Allocate stack for back-tracking up CFG.  */
  stack = XNEWVEC (edge_iterator, n_basic_blocks_for_fn (cfun) + 1);
  sp = 0;

  /* Push the first edge on to the stack.  */
  stack[sp++] = ei_start (ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs);

  while (sp)
    {
      edge_iterator ei;
      basic_block src;
      basic_block dest;

      /* Look at the edge on the top of the stack.  */
      ei = stack[sp - 1];
      src = ei_edge (ei)->src;
      dest = ei_edge (ei)->dest;

      /* Check if the edge destination has been visited yet.  */
      if (!VTI (dest)->visited)
	{
	  rtx_insn *insn;
	  HOST_WIDE_INT pre, post, offset;
	  VTI (dest)->visited = true;
	  VTI (dest)->in.stack_adjust = offset = VTI (src)->out.stack_adjust;

	  if (dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
	    for (insn = BB_HEAD (dest);
		 insn != NEXT_INSN (BB_END (dest));
		 insn = NEXT_INSN (insn))
	      if (INSN_P (insn))
		{
		  insn_stack_adjust_offset_pre_post (insn, &pre, &post);
		  offset += pre + post;
		}

	  VTI (dest)->out.stack_adjust = offset;

	  if (EDGE_COUNT (dest->succs) > 0)
	    /* Since the DEST node has been visited for the first
	       time, check its successors.  */
	    stack[sp++] = ei_start (dest->succs);
	}
      else
	{
	  /* We can end up with different stack adjustments for the exit block
	     of a shrink-wrapped function if stack_adjust_offset_pre_post
	     doesn't understand the rtx pattern used to restore the stack
	     pointer in the epilogue.  For example, on s390(x), the stack
	     pointer is often restored via a load-multiple instruction
	     and so no stack_adjust offset is recorded for it.  This means
	     that the stack offset at the end of the epilogue block is the
	     same as the offset before the epilogue, whereas other paths
	     to the exit block will have the correct stack_adjust.

	     It is safe to ignore these differences because (a) we never
	     use the stack_adjust for the exit block in this pass and
	     (b) dwarf2cfi checks whether the CFA notes in a shrink-wrapped
	     function are correct.

	     We must check whether the adjustments on other edges are
	     the same though.  */
	  if (dest != EXIT_BLOCK_PTR_FOR_FN (cfun)
	      && VTI (dest)->in.stack_adjust != VTI (src)->out.stack_adjust)
	    {
	      free (stack);
	      return false;
	    }

	  if (! ei_one_before_end_p (ei))
	    /* Go to the next edge.  */
	    ei_next (&stack[sp - 1]);
	  else
	    /* Return to previous level if there are no more edges.  */
	    sp--;
	}
    }

  free (stack);
  return true;
}

/* arg_pointer_rtx resp. frame_pointer_rtx if stack_pointer_rtx or
   hard_frame_pointer_rtx is being mapped to it and offset for it.  */
static rtx cfa_base_rtx;
static HOST_WIDE_INT cfa_base_offset;

/* Compute a CFA-based value for an ADJUSTMENT made to stack_pointer_rtx
   or hard_frame_pointer_rtx.  */

static inline rtx
compute_cfa_pointer (poly_int64 adjustment)
{
  return plus_constant (Pmode, cfa_base_rtx, adjustment + cfa_base_offset);
}

/* Adjustment for hard_frame_pointer_rtx to cfa base reg,
   or -1 if the replacement shouldn't be done.  */
static poly_int64 hard_frame_pointer_adjustment = -1;

/* Data for adjust_mems callback.  */

class adjust_mem_data
{
public:
  bool store;
  machine_mode mem_mode;
  HOST_WIDE_INT stack_adjust;
  auto_vec<rtx> side_effects;
};

/* Helper for adjust_mems.  Return true if X is suitable for
   transformation of wider mode arithmetics to narrower mode.  */

static bool
use_narrower_mode_test (rtx x, const_rtx subreg)
{
  subrtx_var_iterator::array_type array;
  FOR_EACH_SUBRTX_VAR (iter, array, x, NONCONST)
    {
      rtx x = *iter;
      if (CONSTANT_P (x))
	iter.skip_subrtxes ();
      else
	switch (GET_CODE (x))
	  {
	  case REG:
	    if (cselib_lookup (x, GET_MODE (SUBREG_REG (subreg)), 0, VOIDmode))
	      return false;
	    if (!validate_subreg (GET_MODE (subreg), GET_MODE (x), x,
				  subreg_lowpart_offset (GET_MODE (subreg),
							 GET_MODE (x))))
	      return false;
	    break;
	  case PLUS:
	  case MINUS:
	  case MULT:
	    break;
	  case ASHIFT:
	    if (GET_MODE (XEXP (x, 1)) != VOIDmode)
	      {
		enum machine_mode mode = GET_MODE (subreg);
		rtx op1 = XEXP (x, 1);
		enum machine_mode op1_mode = GET_MODE (op1);
		if (GET_MODE_PRECISION (as_a <scalar_int_mode> (mode))
		    < GET_MODE_PRECISION (as_a <scalar_int_mode> (op1_mode)))
		  {
		    poly_uint64 byte = subreg_lowpart_offset (mode, op1_mode);
		    if (GET_CODE (op1) == SUBREG || GET_CODE (op1) == CONCAT)
		      {
			if (!simplify_subreg (mode, op1, op1_mode, byte))
			  return false;
		      }
		    else if (!validate_subreg (mode, op1_mode, op1, byte))
		      return false;
		  }
	      }
	    iter.substitute (XEXP (x, 0));
	    break;
	  default:
	    return false;
	  }
    }
  return true;
}

/* Transform X into narrower mode MODE from wider mode WMODE.  */

static rtx
use_narrower_mode (rtx x, scalar_int_mode mode, scalar_int_mode wmode)
{
  rtx op0, op1;
  if (CONSTANT_P (x))
    return lowpart_subreg (mode, x, wmode);
  switch (GET_CODE (x))
    {
    case REG:
      return lowpart_subreg (mode, x, wmode);
    case PLUS:
    case MINUS:
    case MULT:
      op0 = use_narrower_mode (XEXP (x, 0), mode, wmode);
      op1 = use_narrower_mode (XEXP (x, 1), mode, wmode);
      return simplify_gen_binary (GET_CODE (x), mode, op0, op1);
    case ASHIFT:
      op0 = use_narrower_mode (XEXP (x, 0), mode, wmode);
      op1 = XEXP (x, 1);
      /* Ensure shift amount is not wider than mode.  */
      if (GET_MODE (op1) == VOIDmode)
	op1 = lowpart_subreg (mode, op1, wmode);
      else if (GET_MODE_PRECISION (mode)
	       < GET_MODE_PRECISION (as_a <scalar_int_mode> (GET_MODE (op1))))
	op1 = lowpart_subreg (mode, op1, GET_MODE (op1));
      return simplify_gen_binary (ASHIFT, mode, op0, op1);
    default:
      gcc_unreachable ();
    }
}

/* Helper function for adjusting used MEMs.  */

static rtx
adjust_mems (rtx loc, const_rtx old_rtx, void *data)
{
  class adjust_mem_data *amd = (class adjust_mem_data *) data;
  rtx mem, addr = loc, tem;
  machine_mode mem_mode_save;
  bool store_save;
  scalar_int_mode tem_mode, tem_subreg_mode;
  poly_int64 size;
  switch (GET_CODE (loc))
    {
    case REG:
      /* Don't do any sp or fp replacements outside of MEM addresses
         on the LHS.  */
      if (amd->mem_mode == VOIDmode && amd->store)
	return loc;
      if (loc == stack_pointer_rtx
	  && !frame_pointer_needed
	  && cfa_base_rtx)
	return compute_cfa_pointer (amd->stack_adjust);
      else if (loc == hard_frame_pointer_rtx
	       && frame_pointer_needed
	       && maybe_ne (hard_frame_pointer_adjustment, -1)
	       && cfa_base_rtx)
	return compute_cfa_pointer (hard_frame_pointer_adjustment);
      gcc_checking_assert (loc != virtual_incoming_args_rtx);
      return loc;
    case MEM:
      mem = loc;
      if (!amd->store)
	{
	  mem = targetm.delegitimize_address (mem);
	  if (mem != loc && !MEM_P (mem))
	    return simplify_replace_fn_rtx (mem, old_rtx, adjust_mems, data);
	}

      addr = XEXP (mem, 0);
      mem_mode_save = amd->mem_mode;
      amd->mem_mode = GET_MODE (mem);
      store_save = amd->store;
      amd->store = false;
      addr = simplify_replace_fn_rtx (addr, old_rtx, adjust_mems, data);
      amd->store = store_save;
      amd->mem_mode = mem_mode_save;
      if (mem == loc)
	addr = targetm.delegitimize_address (addr);
      if (addr != XEXP (mem, 0))
	mem = replace_equiv_address_nv (mem, addr);
      if (!amd->store)
	mem = avoid_constant_pool_reference (mem);
      return mem;
    case PRE_INC:
    case PRE_DEC:
      size = GET_MODE_SIZE (amd->mem_mode);
      addr = plus_constant (GET_MODE (loc), XEXP (loc, 0),
			    GET_CODE (loc) == PRE_INC ? size : -size);
      /* FALLTHRU */
    case POST_INC:
    case POST_DEC:
      if (addr == loc)
	addr = XEXP (loc, 0);
      gcc_assert (amd->mem_mode != VOIDmode && amd->mem_mode != BLKmode);
      addr = simplify_replace_fn_rtx (addr, old_rtx, adjust_mems, data);
      size = GET_MODE_SIZE (amd->mem_mode);
      tem = plus_constant (GET_MODE (loc), XEXP (loc, 0),
			   (GET_CODE (loc) == PRE_INC
			    || GET_CODE (loc) == POST_INC) ? size : -size);
      store_save = amd->store;
      amd->store = false;
      tem = simplify_replace_fn_rtx (tem, old_rtx, adjust_mems, data);
      amd->store = store_save;
      amd->side_effects.safe_push (gen_rtx_SET (XEXP (loc, 0), tem));
      return addr;
    case PRE_MODIFY:
      addr = XEXP (loc, 1);
      /* FALLTHRU */
    case POST_MODIFY:
      if (addr == loc)
	addr = XEXP (loc, 0);
      gcc_assert (amd->mem_mode != VOIDmode);
      addr = simplify_replace_fn_rtx (addr, old_rtx, adjust_mems, data);
      store_save = amd->store;
      amd->store = false;
      tem = simplify_replace_fn_rtx (XEXP (loc, 1), old_rtx,
				     adjust_mems, data);
      amd->store = store_save;
      amd->side_effects.safe_push (gen_rtx_SET (XEXP (loc, 0), tem));
      return addr;
    case SUBREG:
      /* First try without delegitimization of whole MEMs and
	 avoid_constant_pool_reference, which is more likely to succeed.  */
      store_save = amd->store;
      amd->store = true;
      addr = simplify_replace_fn_rtx (SUBREG_REG (loc), old_rtx, adjust_mems,
				      data);
      amd->store = store_save;
      mem = simplify_replace_fn_rtx (addr, old_rtx, adjust_mems, data);
      if (mem == SUBREG_REG (loc))
	{
	  tem = loc;
	  goto finish_subreg;
	}
      tem = simplify_gen_subreg (GET_MODE (loc), mem,
				 GET_MODE (SUBREG_REG (loc)),
				 SUBREG_BYTE (loc));
      if (tem)
	goto finish_subreg;
      tem = simplify_gen_subreg (GET_MODE (loc), addr,
				 GET_MODE (SUBREG_REG (loc)),
				 SUBREG_BYTE (loc));
      if (tem == NULL_RTX)
	tem = gen_rtx_raw_SUBREG (GET_MODE (loc), addr, SUBREG_BYTE (loc));
    finish_subreg:
      if (MAY_HAVE_DEBUG_BIND_INSNS
	  && GET_CODE (tem) == SUBREG
	  && (GET_CODE (SUBREG_REG (tem)) == PLUS
	      || GET_CODE (SUBREG_REG (tem)) == MINUS
	      || GET_CODE (SUBREG_REG (tem)) == MULT
	      || GET_CODE (SUBREG_REG (tem)) == ASHIFT)
	  && is_a <scalar_int_mode> (GET_MODE (tem), &tem_mode)
	  && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (tem)),
				     &tem_subreg_mode)
	  && (GET_MODE_PRECISION (tem_mode)
	      < GET_MODE_PRECISION (tem_subreg_mode))
	  && subreg_lowpart_p (tem)
	  && use_narrower_mode_test (SUBREG_REG (tem), tem))
	return use_narrower_mode (SUBREG_REG (tem), tem_mode, tem_subreg_mode);
      return tem;
    case ASM_OPERANDS:
      /* Don't do any replacements in second and following
	 ASM_OPERANDS of inline-asm with multiple sets.
	 ASM_OPERANDS_INPUT_VEC, ASM_OPERANDS_INPUT_CONSTRAINT_VEC
	 and ASM_OPERANDS_LABEL_VEC need to be equal between
	 all the ASM_OPERANDs in the insn and adjust_insn will
	 fix this up.  */
      if (ASM_OPERANDS_OUTPUT_IDX (loc) != 0)
	return loc;
      break;
    default:
      break;
    }
  return NULL_RTX;
}

/* Helper function for replacement of uses.  */

static void
adjust_mem_uses (rtx *x, void *data)
{
  rtx new_x = simplify_replace_fn_rtx (*x, NULL_RTX, adjust_mems, data);
  if (new_x != *x)
    validate_change (NULL_RTX, x, new_x, true);
}

/* Helper function for replacement of stores.  */

static void
adjust_mem_stores (rtx loc, const_rtx expr, void *data)
{
  if (MEM_P (loc))
    {
      rtx new_dest = simplify_replace_fn_rtx (SET_DEST (expr), NULL_RTX,
					      adjust_mems, data);
      if (new_dest != SET_DEST (expr))
	{
	  rtx xexpr = CONST_CAST_RTX (expr);
	  validate_change (NULL_RTX, &SET_DEST (xexpr), new_dest, true);
	}
    }
}

/* Simplify INSN.  Remove all {PRE,POST}_{INC,DEC,MODIFY} rtxes,
   replace them with their value in the insn and add the side-effects
   as other sets to the insn.  */

static void
adjust_insn (basic_block bb, rtx_insn *insn)
{
  rtx set;

#ifdef HAVE_window_save
  /* If the target machine has an explicit window save instruction, the
     transformation OUTGOING_REGNO -> INCOMING_REGNO is done there.  */
  if (RTX_FRAME_RELATED_P (insn)
      && find_reg_note (insn, REG_CFA_WINDOW_SAVE, NULL_RTX))
    {
      unsigned int i, nregs = vec_safe_length (windowed_parm_regs);
      rtx rtl = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nregs * 2));
      parm_reg *p;

      FOR_EACH_VEC_SAFE_ELT (windowed_parm_regs, i, p)
	{
	  XVECEXP (rtl, 0, i * 2)
	    = gen_rtx_SET (p->incoming, p->outgoing);
	  /* Do not clobber the attached DECL, but only the REG.  */
	  XVECEXP (rtl, 0, i * 2 + 1)
	    = gen_rtx_CLOBBER (GET_MODE (p->outgoing),
			       gen_raw_REG (GET_MODE (p->outgoing),
					    REGNO (p->outgoing)));
	}

      validate_change (NULL_RTX, &PATTERN (insn), rtl, true);
      return;
    }
#endif

  adjust_mem_data amd;
  amd.mem_mode = VOIDmode;
  amd.stack_adjust = -VTI (bb)->out.stack_adjust;

  amd.store = true;
  note_stores (insn, adjust_mem_stores, &amd);

  amd.store = false;
  if (GET_CODE (PATTERN (insn)) == PARALLEL
      && asm_noperands (PATTERN (insn)) > 0
      && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
    {
      rtx body, set0;
      int i;

      /* inline-asm with multiple sets is tiny bit more complicated,
	 because the 3 vectors in ASM_OPERANDS need to be shared between
	 all ASM_OPERANDS in the instruction.  adjust_mems will
	 not touch ASM_OPERANDS other than the first one, asm_noperands
	 test above needs to be called before that (otherwise it would fail)
	 and afterwards this code fixes it up.  */
      note_uses (&PATTERN (insn), adjust_mem_uses, &amd);
      body = PATTERN (insn);
      set0 = XVECEXP (body, 0, 0);
      gcc_checking_assert (GET_CODE (set0) == SET
			   && GET_CODE (SET_SRC (set0)) == ASM_OPERANDS
			   && ASM_OPERANDS_OUTPUT_IDX (SET_SRC (set0)) == 0);
      for (i = 1; i < XVECLEN (body, 0); i++)
	if (GET_CODE (XVECEXP (body, 0, i)) != SET)
	  break;
	else
	  {
	    set = XVECEXP (body, 0, i);
	    gcc_checking_assert (GET_CODE (SET_SRC (set)) == ASM_OPERANDS
				 && ASM_OPERANDS_OUTPUT_IDX (SET_SRC (set))
				    == i);
	    if (ASM_OPERANDS_INPUT_VEC (SET_SRC (set))
		!= ASM_OPERANDS_INPUT_VEC (SET_SRC (set0))
		|| ASM_OPERANDS_INPUT_CONSTRAINT_VEC (SET_SRC (set))
		   != ASM_OPERANDS_INPUT_CONSTRAINT_VEC (SET_SRC (set0))
		|| ASM_OPERANDS_LABEL_VEC (SET_SRC (set))
		   != ASM_OPERANDS_LABEL_VEC (SET_SRC (set0)))
	      {
		rtx newsrc = shallow_copy_rtx (SET_SRC (set));
		ASM_OPERANDS_INPUT_VEC (newsrc)
		  = ASM_OPERANDS_INPUT_VEC (SET_SRC (set0));
		ASM_OPERANDS_INPUT_CONSTRAINT_VEC (newsrc)
		  = ASM_OPERANDS_INPUT_CONSTRAINT_VEC (SET_SRC (set0));
		ASM_OPERANDS_LABEL_VEC (newsrc)
		  = ASM_OPERANDS_LABEL_VEC (SET_SRC (set0));
		validate_change (NULL_RTX, &SET_SRC (set), newsrc, true);
	      }
	  }
    }
  else
    note_uses (&PATTERN (insn), adjust_mem_uses, &amd);

  /* For read-only MEMs containing some constant, prefer those
     constants.  */
  set = single_set (insn);
  if (set && MEM_P (SET_SRC (set)) && MEM_READONLY_P (SET_SRC (set)))
    {
      rtx note = find_reg_equal_equiv_note (insn);

      if (note && CONSTANT_P (XEXP (note, 0)))
	validate_change (NULL_RTX, &SET_SRC (set), XEXP (note, 0), true);
    }

  if (!amd.side_effects.is_empty ())
    {
      rtx *pat, new_pat;
      int i, oldn;

      pat = &PATTERN (insn);
      if (GET_CODE (*pat) == COND_EXEC)
	pat = &COND_EXEC_CODE (*pat);
      if (GET_CODE (*pat) == PARALLEL)
	oldn = XVECLEN (*pat, 0);
      else
	oldn = 1;
      unsigned int newn = amd.side_effects.length ();
      new_pat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (oldn + newn));
      if (GET_CODE (*pat) == PARALLEL)
	for (i = 0; i < oldn; i++)
	  XVECEXP (new_pat, 0, i) = XVECEXP (*pat, 0, i);
      else
	XVECEXP (new_pat, 0, 0) = *pat;

      rtx effect;
      unsigned int j;
      FOR_EACH_VEC_ELT_REVERSE (amd.side_effects, j, effect)
	XVECEXP (new_pat, 0, j + oldn) = effect;
      validate_change (NULL_RTX, pat, new_pat, true);
    }
}

/* Return the DEBUG_EXPR of a DEBUG_EXPR_DECL or the VALUE in DV.  */
static inline rtx
dv_as_rtx (decl_or_value dv)
{
  tree decl;

  if (dv_is_value_p (dv))
    return dv_as_value (dv);

  decl = dv_as_decl (dv);

  gcc_checking_assert (TREE_CODE (decl) == DEBUG_EXPR_DECL);
  return DECL_RTL_KNOWN_SET (decl);
}

/* Return nonzero if a decl_or_value must not have more than one
   variable part.  The returned value discriminates among various
   kinds of one-part DVs ccording to enum onepart_enum.  */
static inline onepart_enum
dv_onepart_p (decl_or_value dv)
{
  tree decl;

  if (!MAY_HAVE_DEBUG_BIND_INSNS)
    return NOT_ONEPART;

  if (dv_is_value_p (dv))
    return ONEPART_VALUE;

  decl = dv_as_decl (dv);

  if (TREE_CODE (decl) == DEBUG_EXPR_DECL)
    return ONEPART_DEXPR;

  if (target_for_debug_bind (decl) != NULL_TREE)
    return ONEPART_VDECL;

  return NOT_ONEPART;
}

/* Return the variable pool to be used for a dv of type ONEPART.  */
static inline pool_allocator &
onepart_pool (onepart_enum onepart)
{
  return onepart ? valvar_pool : var_pool;
}

/* Allocate a variable_def from the corresponding variable pool.  */
static inline variable *
onepart_pool_allocate (onepart_enum onepart)
{
  return (variable*) onepart_pool (onepart).allocate ();
}

/* Build a decl_or_value out of a decl.  */
static inline decl_or_value
dv_from_decl (tree decl)
{
  decl_or_value dv;
  dv = decl;
  gcc_checking_assert (dv_is_decl_p (dv));
  return dv;
}

/* Build a decl_or_value out of a value.  */
static inline decl_or_value
dv_from_value (rtx value)
{
  decl_or_value dv;
  dv = value;
  gcc_checking_assert (dv_is_value_p (dv));
  return dv;
}

/* Return a value or the decl of a debug_expr as a decl_or_value.  */
static inline decl_or_value
dv_from_rtx (rtx x)
{
  decl_or_value dv;

  switch (GET_CODE (x))
    {
    case DEBUG_EXPR:
      dv = dv_from_decl (DEBUG_EXPR_TREE_DECL (x));
      gcc_checking_assert (DECL_RTL_KNOWN_SET (DEBUG_EXPR_TREE_DECL (x)) == x);
      break;

    case VALUE:
      dv = dv_from_value (x);
      break;

    default:
      gcc_unreachable ();
    }

  return dv;
}

extern void debug_dv (decl_or_value dv);

DEBUG_FUNCTION void
debug_dv (decl_or_value dv)
{
  if (dv_is_value_p (dv))
    debug_rtx (dv_as_value (dv));
  else
    debug_generic_stmt (dv_as_decl (dv));
}

static void loc_exp_dep_clear (variable *var);

/* Free the element of VARIABLE_HTAB (its type is struct variable_def).  */

static void
variable_htab_free (void *elem)
{
  int i;
  variable *var = (variable *) elem;
  location_chain *node, *next;

  gcc_checking_assert (var->refcount > 0);

  var->refcount--;
  if (var->refcount > 0)
    return;

  for (i = 0; i < var->n_var_parts; i++)
    {
      for (node = var->var_part[i].loc_chain; node; node = next)
	{
	  next = node->next;
	  delete node;
	}
      var->var_part[i].loc_chain = NULL;
    }
  if (var->onepart && VAR_LOC_1PAUX (var))
    {
      loc_exp_dep_clear (var);
      if (VAR_LOC_DEP_LST (var))
	VAR_LOC_DEP_LST (var)->pprev = NULL;
      XDELETE (VAR_LOC_1PAUX (var));
      /* These may be reused across functions, so reset
	 e.g. NO_LOC_P.  */
      if (var->onepart == ONEPART_DEXPR)
	set_dv_changed (var->dv, true);
    }
  onepart_pool (var->onepart).remove (var);
}

/* Initialize the set (array) SET of attrs to empty lists.  */

static void
init_attrs_list_set (attrs **set)
{
  int i;

  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    set[i] = NULL;
}

/* Make the list *LISTP empty.  */

static void
attrs_list_clear (attrs **listp)
{
  attrs *list, *next;

  for (list = *listp; list; list = next)
    {
      next = list->next;
      delete list;
    }
  *listp = NULL;
}

/* Return true if the pair of DECL and OFFSET is the member of the LIST.  */

static attrs *
attrs_list_member (attrs *list, decl_or_value dv, HOST_WIDE_INT offset)
{
  for (; list; list = list->next)
    if (dv_as_opaque (list->dv) == dv_as_opaque (dv) && list->offset == offset)
      return list;
  return NULL;
}

/* Insert the triplet DECL, OFFSET, LOC to the list *LISTP.  */

static void
attrs_list_insert (attrs **listp, decl_or_value dv,
		   HOST_WIDE_INT offset, rtx loc)
{
  attrs *list = new attrs;
  list->loc = loc;
  list->dv = dv;
  list->offset = offset;
  list->next = *listp;
  *listp = list;
}

/* Copy all nodes from SRC and create a list *DSTP of the copies.  */

static void
attrs_list_copy (attrs **dstp, attrs *src)
{
  attrs_list_clear (dstp);
  for (; src; src = src->next)
    {
      attrs *n = new attrs;
      n->loc = src->loc;
      n->dv = src->dv;
      n->offset = src->offset;
      n->next = *dstp;
      *dstp = n;
    }
}

/* Add all nodes from SRC which are not in *DSTP to *DSTP.  */

static void
attrs_list_union (attrs **dstp, attrs *src)
{
  for (; src; src = src->next)
    {
      if (!attrs_list_member (*dstp, src->dv, src->offset))
	attrs_list_insert (dstp, src->dv, src->offset, src->loc);
    }
}

/* Combine nodes that are not onepart nodes from SRC and SRC2 into
   *DSTP.  */

static void
attrs_list_mpdv_union (attrs **dstp, attrs *src, attrs *src2)
{
  gcc_assert (!*dstp);
  for (; src; src = src->next)
    {
      if (!dv_onepart_p (src->dv))
	attrs_list_insert (dstp, src->dv, src->offset, src->loc);
    }
  for (src = src2; src; src = src->next)
    {
      if (!dv_onepart_p (src->dv)
	  && !attrs_list_member (*dstp, src->dv, src->offset))
	attrs_list_insert (dstp, src->dv, src->offset, src->loc);
    }
}

/* Shared hashtable support.  */

/* Return true if VARS is shared.  */

static inline bool
shared_hash_shared (shared_hash *vars)
{
  return vars->refcount > 1;
}

/* Return the hash table for VARS.  */

static inline variable_table_type *
shared_hash_htab (shared_hash *vars)
{
  return vars->htab;
}

/* Return true if VAR is shared, or maybe because VARS is shared.  */

static inline bool
shared_var_p (variable *var, shared_hash *vars)
{
  /* Don't count an entry in the changed_variables table as a duplicate.  */
  return ((var->refcount > 1 + (int) var->in_changed_variables)
	  || shared_hash_shared (vars));
}

/* Copy variables into a new hash table.  */

static shared_hash *
shared_hash_unshare (shared_hash *vars)
{
  shared_hash *new_vars = new shared_hash;
  gcc_assert (vars->refcount > 1);
  new_vars->refcount = 1;
  new_vars->htab = new variable_table_type (vars->htab->elements () + 3);
  vars_copy (new_vars->htab, vars->htab);
  vars->refcount--;
  return new_vars;
}

/* Increment reference counter on VARS and return it.  */

static inline shared_hash *
shared_hash_copy (shared_hash *vars)
{
  vars->refcount++;
  return vars;
}

/* Decrement reference counter and destroy hash table if not shared
   anymore.  */

static void
shared_hash_destroy (shared_hash *vars)
{
  gcc_checking_assert (vars->refcount > 0);
  if (--vars->refcount == 0)
    {
      delete vars->htab;
      delete vars;
    }
}

/* Unshare *PVARS if shared and return slot for DV.  If INS is
   INSERT, insert it if not already present.  */

static inline variable **
shared_hash_find_slot_unshare_1 (shared_hash **pvars, decl_or_value dv,
				 hashval_t dvhash, enum insert_option ins)
{
  if (shared_hash_shared (*pvars))
    *pvars = shared_hash_unshare (*pvars);
  return shared_hash_htab (*pvars)->find_slot_with_hash (dv, dvhash, ins);
}

static inline variable **
shared_hash_find_slot_unshare (shared_hash **pvars, decl_or_value dv,
			       enum insert_option ins)
{
  return shared_hash_find_slot_unshare_1 (pvars, dv, dv_htab_hash (dv), ins);
}

/* Return slot for DV, if it is already present in the hash table.
   If it is not present, insert it only VARS is not shared, otherwise
   return NULL.  */

static inline variable **
shared_hash_find_slot_1 (shared_hash *vars, decl_or_value dv, hashval_t dvhash)
{
  return shared_hash_htab (vars)->find_slot_with_hash (dv, dvhash,
						       shared_hash_shared (vars)
						       ? NO_INSERT : INSERT);
}

static inline variable **
shared_hash_find_slot (shared_hash *vars, decl_or_value dv)
{
  return shared_hash_find_slot_1 (vars, dv, dv_htab_hash (dv));
}

/* Return slot for DV only if it is already present in the hash table.  */

static inline variable **
shared_hash_find_slot_noinsert_1 (shared_hash *vars, decl_or_value dv,
				  hashval_t dvhash)
{
  return shared_hash_htab (vars)->find_slot_with_hash (dv, dvhash, NO_INSERT);
}

static inline variable **
shared_hash_find_slot_noinsert (shared_hash *vars, decl_or_value dv)
{
  return shared_hash_find_slot_noinsert_1 (vars, dv, dv_htab_hash (dv));
}

/* Return variable for DV or NULL if not already present in the hash
   table.  */

static inline variable *
shared_hash_find_1 (shared_hash *vars, decl_or_value dv, hashval_t dvhash)
{
  return shared_hash_htab (vars)->find_with_hash (dv, dvhash);
}

static inline variable *
shared_hash_find (shared_hash *vars, decl_or_value dv)
{
  return shared_hash_find_1 (vars, dv, dv_htab_hash (dv));
}

/* Return true if TVAL is better than CVAL as a canonival value.  We
   choose lowest-numbered VALUEs, using the RTX address as a
   tie-breaker.  The idea is to arrange them into a star topology,
   such that all of them are at most one step away from the canonical
   value, and the canonical value has backlinks to all of them, in
   addition to all the actual locations.  We don't enforce this
   topology throughout the entire dataflow analysis, though.
 */

static inline bool
canon_value_cmp (rtx tval, rtx cval)
{
  return !cval
    || CSELIB_VAL_PTR (tval)->uid < CSELIB_VAL_PTR (cval)->uid;
}

static bool dst_can_be_shared;

/* Return a copy of a variable VAR and insert it to dataflow set SET.  */

static variable **
unshare_variable (dataflow_set *set, variable **slot, variable *var,
		  enum var_init_status initialized)
{
  variable *new_var;
  int i;

  new_var = onepart_pool_allocate (var->onepart);
  new_var->dv = var->dv;
  new_var->refcount = 1;
  var->refcount--;
  new_var->n_var_parts = var->n_var_parts;
  new_var->onepart = var->onepart;
  new_var->in_changed_variables = false;

  if (! flag_var_tracking_uninit)
    initialized = VAR_INIT_STATUS_INITIALIZED;

  for (i = 0; i < var->n_var_parts; i++)
    {
      location_chain *node;
      location_chain **nextp;

      if (i == 0 && var->onepart)
	{
	  /* One-part auxiliary data is only used while emitting
	     notes, so propagate it to the new variable in the active
	     dataflow set.  If we're not emitting notes, this will be
	     a no-op.  */
	  gcc_checking_assert (!VAR_LOC_1PAUX (var) || emit_notes);
	  VAR_LOC_1PAUX (new_var) = VAR_LOC_1PAUX (var);
	  VAR_LOC_1PAUX (var) = NULL;
	}
      else
	VAR_PART_OFFSET (new_var, i) = VAR_PART_OFFSET (var, i);
      nextp = &new_var->var_part[i].loc_chain;
      for (node = var->var_part[i].loc_chain; node; node = node->next)
	{
	  location_chain *new_lc;

	  new_lc = new location_chain;
	  new_lc->next = NULL;
	  if (node->init > initialized)
	    new_lc->init = node->init;
	  else
	    new_lc->init = initialized;
	  if (node->set_src && !(MEM_P (node->set_src)))
	    new_lc->set_src = node->set_src;
	  else
	    new_lc->set_src = NULL;
	  new_lc->loc = node->loc;

	  *nextp = new_lc;
	  nextp = &new_lc->next;
	}

      new_var->var_part[i].cur_loc = var->var_part[i].cur_loc;
    }

  dst_can_be_shared = false;
  if (shared_hash_shared (set->vars))
    slot = shared_hash_find_slot_unshare (&set->vars, var->dv, NO_INSERT);
  else if (set->traversed_vars && set->vars != set->traversed_vars)
    slot = shared_hash_find_slot_noinsert (set->vars, var->dv);
  *slot = new_var;
  if (var->in_changed_variables)
    {
      variable **cslot
	= changed_variables->find_slot_with_hash (var->dv,
						  dv_htab_hash (var->dv),
						  NO_INSERT);
      gcc_assert (*cslot == (void *) var);
      var->in_changed_variables = false;
      variable_htab_free (var);
      *cslot = new_var;
      new_var->in_changed_variables = true;
    }
  return slot;
}

/* Copy all variables from hash table SRC to hash table DST.  */

static void
vars_copy (variable_table_type *dst, variable_table_type *src)
{
  variable_iterator_type hi;
  variable *var;

  FOR_EACH_HASH_TABLE_ELEMENT (*src, var, variable, hi)
    {
      variable **dstp;
      var->refcount++;
      dstp = dst->find_slot_with_hash (var->dv, dv_htab_hash (var->dv),
				       INSERT);
      *dstp = var;
    }
}

/* Map a decl to its main debug decl.  */

static inline tree
var_debug_decl (tree decl)
{
  if (decl && VAR_P (decl) && DECL_HAS_DEBUG_EXPR_P (decl))
    {
      tree debugdecl = DECL_DEBUG_EXPR (decl);
      if (DECL_P (debugdecl))
	decl = debugdecl;
    }

  return decl;
}

/* Set the register LOC to contain DV, OFFSET.  */

static void
var_reg_decl_set (dataflow_set *set, rtx loc, enum var_init_status initialized,
		  decl_or_value dv, HOST_WIDE_INT offset, rtx set_src,
		  enum insert_option iopt)
{
  attrs *node;
  bool decl_p = dv_is_decl_p (dv);

  if (decl_p)
    dv = dv_from_decl (var_debug_decl (dv_as_decl (dv)));

  for (node = set->regs[REGNO (loc)]; node; node = node->next)
    if (dv_as_opaque (node->dv) == dv_as_opaque (dv)
	&& node->offset == offset)
      break;
  if (!node)
    attrs_list_insert (&set->regs[REGNO (loc)], dv, offset, loc);
  set_variable_part (set, loc, dv, offset, initialized, set_src, iopt);
}

/* Return true if we should track a location that is OFFSET bytes from
   a variable.  Store the constant offset in *OFFSET_OUT if so.  */

static bool
track_offset_p (poly_int64 offset, HOST_WIDE_INT *offset_out)
{
  HOST_WIDE_INT const_offset;
  if (!offset.is_constant (&const_offset)
      || !IN_RANGE (const_offset, 0, MAX_VAR_PARTS - 1))
    return false;
  *offset_out = const_offset;
  return true;
}

/* Return the offset of a register that track_offset_p says we
   should track.  */

static HOST_WIDE_INT
get_tracked_reg_offset (rtx loc)
{
  HOST_WIDE_INT offset;
  if (!track_offset_p (REG_OFFSET (loc), &offset))
    gcc_unreachable ();
  return offset;
}

/* Set the register to contain REG_EXPR (LOC), REG_OFFSET (LOC).  */

static void
var_reg_set (dataflow_set *set, rtx loc, enum var_init_status initialized,
	     rtx set_src)
{
  tree decl = REG_EXPR (loc);
  HOST_WIDE_INT offset = get_tracked_reg_offset (loc);

  var_reg_decl_set (set, loc, initialized,
		    dv_from_decl (decl), offset, set_src, INSERT);
}

static enum var_init_status
get_init_value (dataflow_set *set, rtx loc, decl_or_value dv)
{
  variable *var;
  int i;
  enum var_init_status ret_val = VAR_INIT_STATUS_UNKNOWN;

  if (! flag_var_tracking_uninit)
    return VAR_INIT_STATUS_INITIALIZED;

  var = shared_hash_find (set->vars, dv);
  if (var)
    {
      for (i = 0; i < var->n_var_parts && ret_val == VAR_INIT_STATUS_UNKNOWN; i++)
	{
	  location_chain *nextp;
	  for (nextp = var->var_part[i].loc_chain; nextp; nextp = nextp->next)
	    if (rtx_equal_p (nextp->loc, loc))
	      {
		ret_val = nextp->init;
		break;
	      }
	}
    }

  return ret_val;
}

/* Delete current content of register LOC in dataflow set SET and set
   the register to contain REG_EXPR (LOC), REG_OFFSET (LOC).  If
   MODIFY is true, any other live copies of the same variable part are
   also deleted from the dataflow set, otherwise the variable part is
   assumed to be copied from another location holding the same
   part.  */

static void
var_reg_delete_and_set (dataflow_set *set, rtx loc, bool modify,
			enum var_init_status initialized, rtx set_src)
{
  tree decl = REG_EXPR (loc);
  HOST_WIDE_INT offset = get_tracked_reg_offset (loc);
  attrs *node, *next;
  attrs **nextp;

  decl = var_debug_decl (decl);

  if (initialized == VAR_INIT_STATUS_UNKNOWN)
    initialized = get_init_value (set, loc, dv_from_decl (decl));

  nextp = &set->regs[REGNO (loc)];
  for (node = *nextp; node; node = next)
    {
      next = node->next;
      if (dv_as_opaque (node->dv) != decl || node->offset != offset)
	{
	  delete_variable_part (set, node->loc, node->dv, node->offset);
	  delete node;
	  *nextp = next;
	}
      else
	{
	  node->loc = loc;
	  nextp = &node->next;
	}
    }
  if (modify)
    clobber_variable_part (set, loc, dv_from_decl (decl), offset, set_src);
  var_reg_set (set, loc, initialized, set_src);
}

/* Delete the association of register LOC in dataflow set SET with any
   variables that aren't onepart.  If CLOBBER is true, also delete any
   other live copies of the same variable part, and delete the
   association with onepart dvs too.  */

static void
var_reg_delete (dataflow_set *set, rtx loc, bool clobber)
{
  attrs **nextp = &set->regs[REGNO (loc)];
  attrs *node, *next;

  HOST_WIDE_INT offset;
  if (clobber && track_offset_p (REG_OFFSET (loc), &offset))
    {
      tree decl = REG_EXPR (loc);

      decl = var_debug_decl (decl);

      clobber_variable_part (set, NULL, dv_from_decl (decl), offset, NULL);
    }

  for (node = *nextp; node; node = next)
    {
      next = node->next;
      if (clobber || !dv_onepart_p (node->dv))
	{
	  delete_variable_part (set, node->loc, node->dv, node->offset);
	  delete node;
	  *nextp = next;
	}
      else
	nextp = &node->next;
    }
}

/* Delete content of register with number REGNO in dataflow set SET.  */

static void
var_regno_delete (dataflow_set *set, int regno)
{
  attrs **reg = &set->regs[regno];
  attrs *node, *next;

  for (node = *reg; node; node = next)
    {
      next = node->next;
      delete_variable_part (set, node->loc, node->dv, node->offset);
      delete node;
    }
  *reg = NULL;
}

/* Return true if I is the negated value of a power of two.  */
static bool
negative_power_of_two_p (HOST_WIDE_INT i)
{
  unsigned HOST_WIDE_INT x = -(unsigned HOST_WIDE_INT)i;
  return pow2_or_zerop (x);
}

/* Strip constant offsets and alignments off of LOC.  Return the base
   expression.  */

static rtx
vt_get_canonicalize_base (rtx loc)
{
  while ((GET_CODE (loc) == PLUS
	  || GET_CODE (loc) == AND)
	 && GET_CODE (XEXP (loc, 1)) == CONST_INT
	 && (GET_CODE (loc) != AND
	     || negative_power_of_two_p (INTVAL (XEXP (loc, 1)))))
    loc = XEXP (loc, 0);

  return loc;
}

/* This caches canonicalized addresses for VALUEs, computed using
   information in the global cselib table.  */
static hash_map<rtx, rtx> *global_get_addr_cache;

/* This caches canonicalized addresses for VALUEs, computed using
   information from the global cache and information pertaining to a
   basic block being analyzed.  */
static hash_map<rtx, rtx> *local_get_addr_cache;

static rtx vt_canonicalize_addr (dataflow_set *, rtx);

/* Return the canonical address for LOC, that must be a VALUE, using a
   cached global equivalence or computing it and storing it in the
   global cache.  */

static rtx
get_addr_from_global_cache (rtx const loc)
{
  rtx x;

  gcc_checking_assert (GET_CODE (loc) == VALUE);

  bool existed;
  rtx *slot = &global_get_addr_cache->get_or_insert (loc, &existed);
  if (existed)
    return *slot;

  x = canon_rtx (get_addr (loc));

  /* Tentative, avoiding infinite recursion.  */
  *slot = x;

  if (x != loc)
    {
      rtx nx = vt_canonicalize_addr (NULL, x);
      if (nx != x)
	{
	  /* The table may have moved during recursion, recompute
	     SLOT.  */
	  *global_get_addr_cache->get (loc) = x = nx;
	}
    }

  return x;
}

/* Return the canonical address for LOC, that must be a VALUE, using a
   cached local equivalence or computing it and storing it in the
   local cache.  */

static rtx
get_addr_from_local_cache (dataflow_set *set, rtx const loc)
{
  rtx x;
  decl_or_value dv;
  variable *var;
  location_chain *l;

  gcc_checking_assert (GET_CODE (loc) == VALUE);

  bool existed;
  rtx *slot = &local_get_addr_cache->get_or_insert (loc, &existed);
  if (existed)
    return *slot;

  x = get_addr_from_global_cache (loc);

  /* Tentative, avoiding infinite recursion.  */
  *slot = x;

  /* Recurse to cache local expansion of X, or if we need to search
     for a VALUE in the expansion.  */
  if (x != loc)
    {
      rtx nx = vt_canonicalize_addr (set, x);
      if (nx != x)
	{
	  slot = local_get_addr_cache->get (loc);
	  *slot = x = nx;
	}
      return x;
    }

  dv = dv_from_rtx (x);
  var = shared_hash_find (set->vars, dv);
  if (!var)
    return x;

  /* Look for an improved equivalent expression.  */
  for (l = var->var_part[0].loc_chain; l; l = l->next)
    {
      rtx base = vt_get_canonicalize_base (l->loc);
      if (GET_CODE (base) == VALUE
	  && canon_value_cmp (base, loc))
	{
	  rtx nx = vt_canonicalize_addr (set, l->loc);
	  if (x != nx)
	    {
	      slot = local_get_addr_cache->get (loc);
	      *slot = x = nx;
	    }
	  break;
	}
    }

  return x;
}

/* Canonicalize LOC using equivalences from SET in addition to those
   in the cselib static table.  It expects a VALUE-based expression,
   and it will only substitute VALUEs with other VALUEs or
   function-global equivalences, so that, if two addresses have base
   VALUEs that are locally or globally related in ways that
   memrefs_conflict_p cares about, they will both canonicalize to
   expressions that have the same base VALUE.

   The use of VALUEs as canonical base addresses enables the canonical
   RTXs to remain unchanged globally, if they resolve to a constant,
   or throughout a basic block otherwise, so that they can be cached
   and the cache needs not be invalidated when REGs, MEMs or such
   change.  */

static rtx
vt_canonicalize_addr (dataflow_set *set, rtx oloc)
{
  poly_int64 ofst = 0, term;
  machine_mode mode = GET_MODE (oloc);
  rtx loc = oloc;
  rtx x;
  bool retry = true;

  while (retry)
    {
      while (GET_CODE (loc) == PLUS
	     && poly_int_rtx_p (XEXP (loc, 1), &term))
	{
	  ofst += term;
	  loc = XEXP (loc, 0);
	}

      /* Alignment operations can't normally be combined, so just
	 canonicalize the base and we're done.  We'll normally have
	 only one stack alignment anyway.  */
      if (GET_CODE (loc) == AND
	  && GET_CODE (XEXP (loc, 1)) == CONST_INT
	  && negative_power_of_two_p (INTVAL (XEXP (loc, 1))))
	{
	  x = vt_canonicalize_addr (set, XEXP (loc, 0));
	  if (x != XEXP (loc, 0))
	    loc = gen_rtx_AND (mode, x, XEXP (loc, 1));
	  retry = false;
	}

      if (GET_CODE (loc) == VALUE)
	{
	  if (set)
	    loc = get_addr_from_local_cache (set, loc);
	  else
	    loc = get_addr_from_global_cache (loc);

	  /* Consolidate plus_constants.  */
	  while (maybe_ne (ofst, 0)
		 && GET_CODE (loc) == PLUS
		 && poly_int_rtx_p (XEXP (loc, 1), &term))
	    {
	      ofst += term;
	      loc = XEXP (loc, 0);
	    }

	  retry = false;
	}
      else
	{
	  x = canon_rtx (loc);
	  if (retry)
	    retry = (x != loc);
	  loc = x;
	}
    }

  /* Add OFST back in.  */
  if (maybe_ne (ofst, 0))
    {
      /* Don't build new RTL if we can help it.  */
      if (strip_offset (oloc, &term) == loc && known_eq (term, ofst))
	return oloc;

      loc = plus_constant (mode, loc, ofst);
    }

  return loc;
}

/* Return true iff there's a true dependence between MLOC and LOC.
   MADDR must be a canonicalized version of MLOC's address.  */

static inline bool
vt_canon_true_dep (dataflow_set *set, rtx mloc, rtx maddr, rtx loc)
{
  if (GET_CODE (loc) != MEM)
    return false;

  rtx addr = vt_canonicalize_addr (set, XEXP (loc, 0));
  if (!canon_true_dependence (mloc, GET_MODE (mloc), maddr, loc, addr))
    return false;

  return true;
}

/* Hold parameters for the hashtab traversal function
   drop_overlapping_mem_locs, see below.  */

struct overlapping_mems
{
  dataflow_set *set;
  rtx loc, addr;
};

/* Remove all MEMs that overlap with COMS->LOC from the location list
   of a hash table entry for a onepart variable.  COMS->ADDR must be a
   canonicalized form of COMS->LOC's address, and COMS->LOC must be
   canonicalized itself.  */

int
drop_overlapping_mem_locs (variable **slot, overlapping_mems *coms)
{
  dataflow_set *set = coms->set;
  rtx mloc = coms->loc, addr = coms->addr;
  variable *var = *slot;

  if (var->onepart != NOT_ONEPART)
    {
      location_chain *loc, **locp;
      bool changed = false;
      rtx cur_loc;

      gcc_assert (var->n_var_parts == 1);

      if (shared_var_p (var, set->vars))
	{
	  for (loc = var->var_part[0].loc_chain; loc; loc = loc->next)
	    if (vt_canon_true_dep (set, mloc, addr, loc->loc))
	      break;

	  if (!loc)
	    return 1;

	  slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN);
	  var = *slot;
	  gcc_assert (var->n_var_parts == 1);
	}

      if (VAR_LOC_1PAUX (var))
	cur_loc = VAR_LOC_FROM (var);
      else
	cur_loc = var->var_part[0].cur_loc;

      for (locp = &var->var_part[0].loc_chain, loc = *locp;
	   loc; loc = *locp)
	{
	  if (!vt_canon_true_dep (set, mloc, addr, loc->loc))
	    {
	      locp = &loc->next;
	      continue;
	    }

	  *locp = loc->next;
	  /* If we have deleted the location which was last emitted
	     we have to emit new location so add the variable to set
	     of changed variables.  */
	  if (cur_loc == loc->loc)
	    {
	      changed = true;
	      var->var_part[0].cur_loc = NULL;
	      if (VAR_LOC_1PAUX (var))
		VAR_LOC_FROM (var) = NULL;
	    }
	  delete loc;
	}

      if (!var->var_part[0].loc_chain)
	{
	  var->n_var_parts--;
	  changed = true;
	}
      if (changed)
	variable_was_changed (var, set);
    }

  return 1;
}

/* Remove from SET all VALUE bindings to MEMs that overlap with LOC.  */

static void
clobber_overlapping_mems (dataflow_set *set, rtx loc)
{
  struct overlapping_mems coms;

  gcc_checking_assert (GET_CODE (loc) == MEM);

  coms.set = set;
  coms.loc = canon_rtx (loc);
  coms.addr = vt_canonicalize_addr (set, XEXP (loc, 0));

  set->traversed_vars = set->vars;
  shared_hash_htab (set->vars)
    ->traverse <overlapping_mems*, drop_overlapping_mem_locs> (&coms);
  set->traversed_vars = NULL;
}

/* Set the location of DV, OFFSET as the MEM LOC.  */

static void
var_mem_decl_set (dataflow_set *set, rtx loc, enum var_init_status initialized,
		  decl_or_value dv, HOST_WIDE_INT offset, rtx set_src,
		  enum insert_option iopt)
{
  if (dv_is_decl_p (dv))
    dv = dv_from_decl (var_debug_decl (dv_as_decl (dv)));

  set_variable_part (set, loc, dv, offset, initialized, set_src, iopt);
}

/* Set the location part of variable MEM_EXPR (LOC) in dataflow set
   SET to LOC.
   Adjust the address first if it is stack pointer based.  */

static void
var_mem_set (dataflow_set *set, rtx loc, enum var_init_status initialized,
	     rtx set_src)
{
  tree decl = MEM_EXPR (loc);
  HOST_WIDE_INT offset = int_mem_offset (loc);

  var_mem_decl_set (set, loc, initialized,
		    dv_from_decl (decl), offset, set_src, INSERT);
}

/* Delete and set the location part of variable MEM_EXPR (LOC) in
   dataflow set SET to LOC.  If MODIFY is true, any other live copies
   of the same variable part are also deleted from the dataflow set,
   otherwise the variable part is assumed to be copied from another
   location holding the same part.
   Adjust the address first if it is stack pointer based.  */

static void
var_mem_delete_and_set (dataflow_set *set, rtx loc, bool modify,
			enum var_init_status initialized, rtx set_src)
{
  tree decl = MEM_EXPR (loc);
  HOST_WIDE_INT offset = int_mem_offset (loc);

  clobber_overlapping_mems (set, loc);
  decl = var_debug_decl (decl);

  if (initialized == VAR_INIT_STATUS_UNKNOWN)
    initialized = get_init_value (set, loc, dv_from_decl (decl));

  if (modify)
    clobber_variable_part (set, NULL, dv_from_decl (decl), offset, set_src);
  var_mem_set (set, loc, initialized, set_src);
}

/* Delete the location part LOC from dataflow set SET.  If CLOBBER is
   true, also delete any other live copies of the same variable part.
   Adjust the address first if it is stack pointer based.  */

static void
var_mem_delete (dataflow_set *set, rtx loc, bool clobber)
{
  tree decl = MEM_EXPR (loc);
  HOST_WIDE_INT offset = int_mem_offset (loc);

  clobber_overlapping_mems (set, loc);
  decl = var_debug_decl (decl);
  if (clobber)
    clobber_variable_part (set, NULL, dv_from_decl (decl), offset, NULL);
  delete_variable_part (set, loc, dv_from_decl (decl), offset);
}

/* Return true if LOC should not be expanded for location expressions,
   or used in them.  */

static inline bool
unsuitable_loc (rtx loc)
{
  switch (GET_CODE (loc))
    {
    case PC:
    case SCRATCH:
    case ASM_INPUT:
    case ASM_OPERANDS:
      return true;

    default:
      return false;
    }
}

/* Bind VAL to LOC in SET.  If MODIFIED, detach LOC from any values
   bound to it.  */

static inline void
val_bind (dataflow_set *set, rtx val, rtx loc, bool modified)
{
  if (REG_P (loc))
    {
      if (modified)
	var_regno_delete (set, REGNO (loc));
      var_reg_decl_set (set, loc, VAR_INIT_STATUS_INITIALIZED,
			dv_from_value (val), 0, NULL_RTX, INSERT);
    }
  else if (MEM_P (loc))
    {
      struct elt_loc_list *l = CSELIB_VAL_PTR (val)->locs;

      if (modified)
	clobber_overlapping_mems (set, loc);

      if (l && GET_CODE (l->loc) == VALUE)
	l = canonical_cselib_val (CSELIB_VAL_PTR (l->loc))->locs;

      /* If this MEM is a global constant, we don't need it in the
	 dynamic tables.  ??? We should test this before emitting the
	 micro-op in the first place.  */
      while (l)
	if (GET_CODE (l->loc) == MEM && XEXP (l->loc, 0) == XEXP (loc, 0))
	  break;
	else
	  l = l->next;

      if (!l)
	var_mem_decl_set (set, loc, VAR_INIT_STATUS_INITIALIZED,
			  dv_from_value (val), 0, NULL_RTX, INSERT);
    }
  else
    {
      /* Other kinds of equivalences are necessarily static, at least
	 so long as we do not perform substitutions while merging
	 expressions.  */
      gcc_unreachable ();
      set_variable_part (set, loc, dv_from_value (val), 0,
			 VAR_INIT_STATUS_INITIALIZED, NULL_RTX, INSERT);
    }
}

/* Bind a value to a location it was just stored in.  If MODIFIED
   holds, assume the location was modified, detaching it from any
   values bound to it.  */

static void
val_store (dataflow_set *set, rtx val, rtx loc, rtx_insn *insn,
	   bool modified)
{
  cselib_val *v = CSELIB_VAL_PTR (val);

  gcc_assert (cselib_preserved_value_p (v));

  if (dump_file)
    {
      fprintf (dump_file, "%i: ", insn ? INSN_UID (insn) : 0);
      print_inline_rtx (dump_file, loc, 0);
      fprintf (dump_file, " evaluates to ");
      print_inline_rtx (dump_file, val, 0);
      if (v->locs)
	{
	  struct elt_loc_list *l;
	  for (l = v->locs; l; l = l->next)
	    {
	      fprintf (dump_file, "\n%i: ", INSN_UID (l->setting_insn));
	      print_inline_rtx (dump_file, l->loc, 0);
	    }
	}
      fprintf (dump_file, "\n");
    }

  gcc_checking_assert (!unsuitable_loc (loc));

  val_bind (set, val, loc, modified);
}

/* Clear (canonical address) slots that reference X.  */

bool
local_get_addr_clear_given_value (rtx const &, rtx *slot, rtx x)
{
  if (vt_get_canonicalize_base (*slot) == x)
    *slot = NULL;
  return true;
}

/* Reset this node, detaching all its equivalences.  Return the slot
   in the variable hash table that holds dv, if there is one.  */

static void
val_reset (dataflow_set *set, decl_or_value dv)
{
  variable *var = shared_hash_find (set->vars, dv) ;
  location_chain *node;
  rtx cval;

  if (!var || !var->n_var_parts)
    return;

  gcc_assert (var->n_var_parts == 1);

  if (var->onepart == ONEPART_VALUE)
    {
      rtx x = dv_as_value (dv);

      /* Relationships in the global cache don't change, so reset the
	 local cache entry only.  */
      rtx *slot = local_get_addr_cache->get (x);
      if (slot)
	{
	  /* If the value resolved back to itself, odds are that other
	     values may have cached it too.  These entries now refer
	     to the old X, so detach them too.  Entries that used the
	     old X but resolved to something else remain ok as long as
	     that something else isn't also reset.  */
	  if (*slot == x)
	    local_get_addr_cache
	      ->traverse<rtx, local_get_addr_clear_given_value> (x);
	  *slot = NULL;
	}
    }

  cval = NULL;
  for (node = var->var_part[0].loc_chain; node; node = node->next)
    if (GET_CODE (node->loc) == VALUE
	&& canon_value_cmp (node->loc, cval))
      cval = node->loc;

  for (node = var->var_part[0].loc_chain; node; node = node->next)
    if (GET_CODE (node->loc) == VALUE && cval != node->loc)
      {
	/* Redirect the equivalence link to the new canonical
	   value, or simply remove it if it would point at
	   itself.  */
	if (cval)
	  set_variable_part (set, cval, dv_from_value (node->loc),
			     0, node->init, node->set_src, NO_INSERT);
	delete_variable_part (set, dv_as_value (dv),
			      dv_from_value (node->loc), 0);
      }

  if (cval)
    {
      decl_or_value cdv = dv_from_value (cval);

      /* Keep the remaining values connected, accumulating links
	 in the canonical value.  */
      for (node = var->var_part[0].loc_chain; node; node = node->next)
	{
	  if (node->loc == cval)
	    continue;
	  else if (GET_CODE (node->loc) == REG)
	    var_reg_decl_set (set, node->loc, node->init, cdv, 0,
			      node->set_src, NO_INSERT);
	  else if (GET_CODE (node->loc) == MEM)
	    var_mem_decl_set (set, node->loc, node->init, cdv, 0,
			      node->set_src, NO_INSERT);
	  else
	    set_variable_part (set, node->loc, cdv, 0,
			       node->init, node->set_src, NO_INSERT);
	}
    }

  /* We remove this last, to make sure that the canonical value is not
     removed to the point of requiring reinsertion.  */
  if (cval)
    delete_variable_part (set, dv_as_value (dv), dv_from_value (cval), 0);

  clobber_variable_part (set, NULL, dv, 0, NULL);
}

/* Find the values in a given location and map the val to another
   value, if it is unique, or add the location as one holding the
   value.  */

static void
val_resolve (dataflow_set *set, rtx val, rtx loc, rtx_insn *insn)
{
  decl_or_value dv = dv_from_value (val);

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      if (insn)
	fprintf (dump_file, "%i: ", INSN_UID (insn));
      else
	fprintf (dump_file, "head: ");
      print_inline_rtx (dump_file, val, 0);
      fputs (" is at ", dump_file);
      print_inline_rtx (dump_file, loc, 0);
      fputc ('\n', dump_file);
    }

  val_reset (set, dv);

  gcc_checking_assert (!unsuitable_loc (loc));

  if (REG_P (loc))
    {
      attrs *node, *found = NULL;

      for (node = set->regs[REGNO (loc)]; node; node = node->next)
	if (dv_is_value_p (node->dv)
	    && GET_MODE (dv_as_value (node->dv)) == GET_MODE (loc))
	  {
	    found = node;

	    /* Map incoming equivalences.  ??? Wouldn't it be nice if
	     we just started sharing the location lists?  Maybe a
	     circular list ending at the value itself or some
	     such.  */
	    set_variable_part (set, dv_as_value (node->dv),
			       dv_from_value (val), node->offset,
			       VAR_INIT_STATUS_INITIALIZED, NULL_RTX, INSERT);
	    set_variable_part (set, val, node->dv, node->offset,
			       VAR_INIT_STATUS_INITIALIZED, NULL_RTX, INSERT);
	  }

      /* If we didn't find any equivalence, we need to remember that
	 this value is held in the named register.  */
      if (found)
	return;
    }
  /* ??? Attempt to find and merge equivalent MEMs or other
     expressions too.  */

  val_bind (set, val, loc, false);
}

/* Initialize dataflow set SET to be empty.
   VARS_SIZE is the initial size of hash table VARS.  */

static void
dataflow_set_init (dataflow_set *set)
{
  init_attrs_list_set (set->regs);
  set->vars = shared_hash_copy (empty_shared_hash);
  set->stack_adjust = 0;
  set->traversed_vars = NULL;
}

/* Delete the contents of dataflow set SET.  */

static void
dataflow_set_clear (dataflow_set *set)
{
  int i;

  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    attrs_list_clear (&set->regs[i]);

  shared_hash_destroy (set->vars);
  set->vars = shared_hash_copy (empty_shared_hash);
}

/* Copy the contents of dataflow set SRC to DST.  */

static void
dataflow_set_copy (dataflow_set *dst, dataflow_set *src)
{
  int i;

  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    attrs_list_copy (&dst->regs[i], src->regs[i]);

  shared_hash_destroy (dst->vars);
  dst->vars = shared_hash_copy (src->vars);
  dst->stack_adjust = src->stack_adjust;
}

/* Information for merging lists of locations for a given offset of variable.
 */
struct variable_union_info
{
  /* Node of the location chain.  */
  location_chain *lc;

  /* The sum of positions in the input chains.  */
  int pos;

  /* The position in the chain of DST dataflow set.  */
  int pos_dst;
};

/* Buffer for location list sorting and its allocated size.  */
static struct variable_union_info *vui_vec;
static int vui_allocated;

/* Compare function for qsort, order the structures by POS element.  */

static int
variable_union_info_cmp_pos (const void *n1, const void *n2)
{
  const struct variable_union_info *const i1 =
    (const struct variable_union_info *) n1;
  const struct variable_union_info *const i2 =
    ( const struct variable_union_info *) n2;

  if (i1->pos != i2->pos)
    return i1->pos - i2->pos;

  return (i1->pos_dst - i2->pos_dst);
}

/* Compute union of location parts of variable *SLOT and the same variable
   from hash table DATA.  Compute "sorted" union of the location chains
   for common offsets, i.e. the locations of a variable part are sorted by
   a priority where the priority is the sum of the positions in the 2 chains
   (if a location is only in one list the position in the second list is
   defined to be larger than the length of the chains).
   When we are updating the location parts the newest location is in the
   beginning of the chain, so when we do the described "sorted" union
   we keep the newest locations in the beginning.  */

static int
variable_union (variable *src, dataflow_set *set)
{
  variable *dst;
  variable **dstp;
  int i, j, k;

  dstp = shared_hash_find_slot (set->vars, src->dv);
  if (!dstp || !*dstp)
    {
      src->refcount++;

      dst_can_be_shared = false;
      if (!dstp)
	dstp = shared_hash_find_slot_unshare (&set->vars, src->dv, INSERT);

      *dstp = src;

      /* Continue traversing the hash table.  */
      return 1;
    }
  else
    dst = *dstp;

  gcc_assert (src->n_var_parts);
  gcc_checking_assert (src->onepart == dst->onepart);

  /* We can combine one-part variables very efficiently, because their
     entries are in canonical order.  */
  if (src->onepart)
    {
      location_chain **nodep, *dnode, *snode;

      gcc_assert (src->n_var_parts == 1
		  && dst->n_var_parts == 1);

      snode = src->var_part[0].loc_chain;
      gcc_assert (snode);

    restart_onepart_unshared:
      nodep = &dst->var_part[0].loc_chain;
      dnode = *nodep;
      gcc_assert (dnode);

      while (snode)
	{
	  int r = dnode ? loc_cmp (dnode->loc, snode->loc) : 1;

	  if (r > 0)
	    {
	      location_chain *nnode;

	      if (shared_var_p (dst, set->vars))
		{
		  dstp = unshare_variable (set, dstp, dst,
					   VAR_INIT_STATUS_INITIALIZED);
		  dst = *dstp;
		  goto restart_onepart_unshared;
		}

	      *nodep = nnode = new location_chain;
	      nnode->loc = snode->loc;
	      nnode->init = snode->init;
	      if (!snode->set_src || MEM_P (snode->set_src))
		nnode->set_src = NULL;
	      else
		nnode->set_src = snode->set_src;
	      nnode->next = dnode;
	      dnode = nnode;
	    }
	  else if (r == 0)
	    gcc_checking_assert (rtx_equal_p (dnode->loc, snode->loc));

	  if (r >= 0)
	    snode = snode->next;

	  nodep = &dnode->next;
	  dnode = *nodep;
	}

      return 1;
    }

  gcc_checking_assert (!src->onepart);

  /* Count the number of location parts, result is K.  */
  for (i = 0, j = 0, k = 0;
       i < src->n_var_parts && j < dst->n_var_parts; k++)
    {
      if (VAR_PART_OFFSET (src, i) == VAR_PART_OFFSET (dst, j))
	{
	  i++;
	  j++;
	}
      else if (VAR_PART_OFFSET (src, i) < VAR_PART_OFFSET (dst, j))
	i++;
      else
	j++;
    }
  k += src->n_var_parts - i;
  k += dst->n_var_parts - j;

  /* We track only variables whose size is <= MAX_VAR_PARTS bytes
     thus there are at most MAX_VAR_PARTS different offsets.  */
  gcc_checking_assert (dst->onepart ? k == 1 : k <= MAX_VAR_PARTS);

  if (dst->n_var_parts != k && shared_var_p (dst, set->vars))
    {
      dstp = unshare_variable (set, dstp, dst, VAR_INIT_STATUS_UNKNOWN);
      dst = *dstp;
    }

  i = src->n_var_parts - 1;
  j = dst->n_var_parts - 1;
  dst->n_var_parts = k;

  for (k--; k >= 0; k--)
    {
      location_chain *node, *node2;

      if (i >= 0 && j >= 0
	  && VAR_PART_OFFSET (src, i) == VAR_PART_OFFSET (dst, j))
	{
	  /* Compute the "sorted" union of the chains, i.e. the locations which
	     are in both chains go first, they are sorted by the sum of
	     positions in the chains.  */
	  int dst_l, src_l;
	  int ii, jj, n;
	  struct variable_union_info *vui;

	  /* If DST is shared compare the location chains.
	     If they are different we will modify the chain in DST with
	     high probability so make a copy of DST.  */
	  if (shared_var_p (dst, set->vars))
	    {
	      for (node = src->var_part[i].loc_chain,
		   node2 = dst->var_part[j].loc_chain; node && node2;
		   node = node->next, node2 = node2->next)
		{
		  if (!((REG_P (node2->loc)
			 && REG_P (node->loc)
			 && REGNO (node2->loc) == REGNO (node->loc))
			|| rtx_equal_p (node2->loc, node->loc)))
		    {
		      if (node2->init < node->init)
		        node2->init = node->init;
		      break;
		    }
		}
	      if (node || node2)
		{
		  dstp = unshare_variable (set, dstp, dst,
					   VAR_INIT_STATUS_UNKNOWN);
		  dst = (variable *)*dstp;
		}
	    }

	  src_l = 0;
	  for (node = src->var_part[i].loc_chain; node; node = node->next)
	    src_l++;
	  dst_l = 0;
	  for (node = dst->var_part[j].loc_chain; node; node = node->next)
	    dst_l++;

	  if (dst_l == 1)
	    {
	      /* The most common case, much simpler, no qsort is needed.  */
	      location_chain *dstnode = dst->var_part[j].loc_chain;
	      dst->var_part[k].loc_chain = dstnode;
	      VAR_PART_OFFSET (dst, k) = VAR_PART_OFFSET (dst, j);
	      node2 = dstnode;
	      for (node = src->var_part[i].loc_chain; node; node = node->next)
		if (!((REG_P (dstnode->loc)
		       && REG_P (node->loc)
		       && REGNO (dstnode->loc) == REGNO (node->loc))
		      || rtx_equal_p (dstnode->loc, node->loc)))
		  {
		    location_chain *new_node;

		    /* Copy the location from SRC.  */
		    new_node = new location_chain;
		    new_node->loc = node->loc;
		    new_node->init = node->init;
		    if (!node->set_src || MEM_P (node->set_src))
		      new_node->set_src = NULL;
		    else
		      new_node->set_src = node->set_src;
		    node2->next = new_node;
		    node2 = new_node;
		  }
	      node2->next = NULL;
	    }
	  else
	    {
	      if (src_l + dst_l > vui_allocated)
		{
		  vui_allocated = MAX (vui_allocated * 2, src_l + dst_l);
		  vui_vec = XRESIZEVEC (struct variable_union_info, vui_vec,
					vui_allocated);
		}
	      vui = vui_vec;

	      /* Fill in the locations from DST.  */
	      for (node = dst->var_part[j].loc_chain, jj = 0; node;
		   node = node->next, jj++)
		{
		  vui[jj].lc = node;
		  vui[jj].pos_dst = jj;

		  /* Pos plus value larger than a sum of 2 valid positions.  */
		  vui[jj].pos = jj + src_l + dst_l;
		}

	      /* Fill in the locations from SRC.  */
	      n = dst_l;
	      for (node = src->var_part[i].loc_chain, ii = 0; node;
		   node = node->next, ii++)
		{
		  /* Find location from NODE.  */
		  for (jj = 0; jj < dst_l; jj++)
		    {
		      if ((REG_P (vui[jj].lc->loc)
			   && REG_P (node->loc)
			   && REGNO (vui[jj].lc->loc) == REGNO (node->loc))
			  || rtx_equal_p (vui[jj].lc->loc, node->loc))
			{
			  vui[jj].pos = jj + ii;
			  break;
			}
		    }
		  if (jj >= dst_l)	/* The location has not been found.  */
		    {
		      location_chain *new_node;

		      /* Copy the location from SRC.  */
		      new_node = new location_chain;
		      new_node->loc = node->loc;
		      new_node->init = node->init;
		      if (!node->set_src || MEM_P (node->set_src))
			new_node->set_src = NULL;
		      else
			new_node->set_src = node->set_src;
		      vui[n].lc = new_node;
		      vui[n].pos_dst = src_l + dst_l;
		      vui[n].pos = ii + src_l + dst_l;
		      n++;
		    }
		}

	      if (dst_l == 2)
		{
		  /* Special case still very common case.  For dst_l == 2
		     all entries dst_l ... n-1 are sorted, with for i >= dst_l
		     vui[i].pos == i + src_l + dst_l.  */
		  if (vui[0].pos > vui[1].pos)
		    {
		      /* Order should be 1, 0, 2... */
		      dst->var_part[k].loc_chain = vui[1].lc;
		      vui[1].lc->next = vui[0].lc;
		      if (n >= 3)
			{
			  vui[0].lc->next = vui[2].lc;
			  vui[n - 1].lc->next = NULL;
			}
		      else
			vui[0].lc->next = NULL;
		      ii = 3;
		    }
		  else
		    {
		      dst->var_part[k].loc_chain = vui[0].lc;
		      if (n >= 3 && vui[2].pos < vui[1].pos)
			{
			  /* Order should be 0, 2, 1, 3... */
			  vui[0].lc->next = vui[2].lc;
			  vui[2].lc->next = vui[1].lc;
			  if (n >= 4)
			    {
			      vui[1].lc->next = vui[3].lc;
			      vui[n - 1].lc->next = NULL;
			    }
			  else
			    vui[1].lc->next = NULL;
			  ii = 4;
			}
		      else
			{
			  /* Order should be 0, 1, 2... */
			  ii = 1;
			  vui[n - 1].lc->next = NULL;
			}
		    }
		  for (; ii < n; ii++)
		    vui[ii - 1].lc->next = vui[ii].lc;
		}
	      else
		{
		  qsort (vui, n, sizeof (struct variable_union_info),
			 variable_union_info_cmp_pos);

		  /* Reconnect the nodes in sorted order.  */
		  for (ii = 1; ii < n; ii++)
		    vui[ii - 1].lc->next = vui[ii].lc;
		  vui[n - 1].lc->next = NULL;
		  dst->var_part[k].loc_chain = vui[0].lc;
		}

	      VAR_PART_OFFSET (dst, k) = VAR_PART_OFFSET (dst, j);
	    }
	  i--;
	  j--;
	}
      else if ((i >= 0 && j >= 0
		&& VAR_PART_OFFSET (src, i) < VAR_PART_OFFSET (dst, j))
	       || i < 0)
	{
	  dst->var_part[k] = dst->var_part[j];
	  j--;
	}
      else if ((i >= 0 && j >= 0
		&& VAR_PART_OFFSET (src, i) > VAR_PART_OFFSET (dst, j))
	       || j < 0)
	{
	  location_chain **nextp;

	  /* Copy the chain from SRC.  */
	  nextp = &dst->var_part[k].loc_chain;
	  for (node = src->var_part[i].loc_chain; node; node = node->next)
	    {
	      location_chain *new_lc;

	      new_lc = new location_chain;
	      new_lc->next = NULL;
	      new_lc->init = node->init;
	      if (!node->set_src || MEM_P (node->set_src))
		new_lc->set_src = NULL;
	      else
		new_lc->set_src = node->set_src;
	      new_lc->loc = node->loc;

	      *nextp = new_lc;
	      nextp = &new_lc->next;
	    }

	  VAR_PART_OFFSET (dst, k) = VAR_PART_OFFSET (src, i);
	  i--;
	}
      dst->var_part[k].cur_loc = NULL;
    }

  if (flag_var_tracking_uninit)
    for (i = 0; i < src->n_var_parts && i < dst->n_var_parts; i++)
      {
	location_chain *node, *node2;
	for (node = src->var_part[i].loc_chain; node; node = node->next)
	  for (node2 = dst->var_part[i].loc_chain; node2; node2 = node2->next)
	    if (rtx_equal_p (node->loc, node2->loc))
	      {
		if (node->init > node2->init)
		  node2->init = node->init;
	      }
      }

  /* Continue traversing the hash table.  */
  return 1;
}

/* Compute union of dataflow sets SRC and DST and store it to DST.  */

static void
dataflow_set_union (dataflow_set *dst, dataflow_set *src)
{
  int i;

  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    attrs_list_union (&dst->regs[i], src->regs[i]);

  if (dst->vars == empty_shared_hash)
    {
      shared_hash_destroy (dst->vars);
      dst->vars = shared_hash_copy (src->vars);
    }
  else
    {
      variable_iterator_type hi;
      variable *var;

      FOR_EACH_HASH_TABLE_ELEMENT (*shared_hash_htab (src->vars),
				   var, variable, hi)
	variable_union (var, dst);
    }
}

/* Whether the value is currently being expanded.  */
#define VALUE_RECURSED_INTO(x) \
  (RTL_FLAG_CHECK2 ("VALUE_RECURSED_INTO", (x), VALUE, DEBUG_EXPR)->used)

/* Whether no expansion was found, saving useless lookups.
   It must only be set when VALUE_CHANGED is clear.  */
#define NO_LOC_P(x) \
  (RTL_FLAG_CHECK2 ("NO_LOC_P", (x), VALUE, DEBUG_EXPR)->return_val)

/* Whether cur_loc in the value needs to be (re)computed.  */
#define VALUE_CHANGED(x) \
  (RTL_FLAG_CHECK1 ("VALUE_CHANGED", (x), VALUE)->frame_related)
/* Whether cur_loc in the decl needs to be (re)computed.  */
#define DECL_CHANGED(x) TREE_VISITED (x)

/* Record (if NEWV) that DV needs to have its cur_loc recomputed.  For
   user DECLs, this means they're in changed_variables.  Values and
   debug exprs may be left with this flag set if no user variable
   requires them to be evaluated.  */

static inline void
set_dv_changed (decl_or_value dv, bool newv)
{
  switch (dv_onepart_p (dv))
    {
    case ONEPART_VALUE:
      if (newv)
	NO_LOC_P (dv_as_value (dv)) = false;
      VALUE_CHANGED (dv_as_value (dv)) = newv;
      break;

    case ONEPART_DEXPR:
      if (newv)
	NO_LOC_P (DECL_RTL_KNOWN_SET (dv_as_decl (dv))) = false;
      /* Fall through.  */

    default:
      DECL_CHANGED (dv_as_decl (dv)) = newv;
      break;
    }
}

/* Return true if DV needs to have its cur_loc recomputed.  */

static inline bool
dv_changed_p (decl_or_value dv)
{
  return (dv_is_value_p (dv)
	  ? VALUE_CHANGED (dv_as_value (dv))
	  : DECL_CHANGED (dv_as_decl (dv)));
}

/* Return a location list node whose loc is rtx_equal to LOC, in the
   location list of a one-part variable or value VAR, or in that of
   any values recursively mentioned in the location lists.  VARS must
   be in star-canonical form.  */

static location_chain *
find_loc_in_1pdv (rtx loc, variable *var, variable_table_type *vars)
{
  location_chain *node;
  enum rtx_code loc_code;

  if (!var)
    return NULL;

  gcc_checking_assert (var->onepart);

  if (!var->n_var_parts)
    return NULL;

  gcc_checking_assert (loc != dv_as_opaque (var->dv));

  loc_code = GET_CODE (loc);
  for (node = var->var_part[0].loc_chain; node; node = node->next)
    {
      decl_or_value dv;
      variable *rvar;

      if (GET_CODE (node->loc) != loc_code)
	{
	  if (GET_CODE (node->loc) != VALUE)
	    continue;
	}
      else if (loc == node->loc)
	return node;
      else if (loc_code != VALUE)
	{
	  if (rtx_equal_p (loc, node->loc))
	    return node;
	  continue;
	}

      /* Since we're in star-canonical form, we don't need to visit
	 non-canonical nodes: one-part variables and non-canonical
	 values would only point back to the canonical node.  */
      if (dv_is_value_p (var->dv)
	  && !canon_value_cmp (node->loc, dv_as_value (var->dv)))
	{
	  /* Skip all subsequent VALUEs.  */
	  while (node->next && GET_CODE (node->next->loc) == VALUE)
	    {
	      node = node->next;
	      gcc_checking_assert (!canon_value_cmp (node->loc,
						     dv_as_value (var->dv)));
	      if (loc == node->loc)
		return node;
	    }
	  continue;
	}

      gcc_checking_assert (node == var->var_part[0].loc_chain);
      gcc_checking_assert (!node->next);

      dv = dv_from_value (node->loc);
      rvar = vars->find_with_hash (dv, dv_htab_hash (dv));
      return find_loc_in_1pdv (loc, rvar, vars);
    }

  /* ??? Gotta look in cselib_val locations too.  */

  return NULL;
}

/* Hash table iteration argument passed to variable_merge.  */
struct dfset_merge
{
  /* The set in which the merge is to be inserted.  */
  dataflow_set *dst;
  /* The set that we're iterating in.  */
  dataflow_set *cur;
  /* The set that may contain the other dv we are to merge with.  */
  dataflow_set *src;
  /* Number of onepart dvs in src.  */
  int src_onepart_cnt;
};

/* Insert LOC in *DNODE, if it's not there yet.  The list must be in
   loc_cmp order, and it is maintained as such.  */

static void
insert_into_intersection (location_chain **nodep, rtx loc,
			  enum var_init_status status)
{
  location_chain *node;
  int r;

  for (node = *nodep; node; nodep = &node->next, node = *nodep)
    if ((r = loc_cmp (node->loc, loc)) == 0)
      {
	node->init = MIN (node->init, status);
	return;
      }
    else if (r > 0)
      break;

  node = new location_chain;

  node->loc = loc;
  node->set_src = NULL;
  node->init = status;
  node->next = *nodep;
  *nodep = node;
}

/* Insert in DEST the intersection of the locations present in both
   S1NODE and S2VAR, directly or indirectly.  S1NODE is from a
   variable in DSM->cur, whereas S2VAR is from DSM->src.  dvar is in
   DSM->dst.  */

static void
intersect_loc_chains (rtx val, location_chain **dest, struct dfset_merge *dsm,
		      location_chain *s1node, variable *s2var)
{
  dataflow_set *s1set = dsm->cur;
  dataflow_set *s2set = dsm->src;
  location_chain *found;

  if (s2var)
    {
      location_chain *s2node;

      gcc_checking_assert (s2var->onepart);

      if (s2var->n_var_parts)
	{
	  s2node = s2var->var_part[0].loc_chain;

	  for (; s1node && s2node;
	       s1node = s1node->next, s2node = s2node->next)
	    if (s1node->loc != s2node->loc)
	      break;
	    else if (s1node->loc == val)
	      continue;
	    else
	      insert_into_intersection (dest, s1node->loc,
					MIN (s1node->init, s2node->init));
	}
    }

  for (; s1node; s1node = s1node->next)
    {
      if (s1node->loc == val)
	continue;

      if ((found = find_loc_in_1pdv (s1node->loc, s2var,
				     shared_hash_htab (s2set->vars))))
	{
	  insert_into_intersection (dest, s1node->loc,
				    MIN (s1node->init, found->init));
	  continue;
	}

      if (GET_CODE (s1node->loc) == VALUE
	  && !VALUE_RECURSED_INTO (s1node->loc))
	{
	  decl_or_value dv = dv_from_value (s1node->loc);
	  variable *svar = shared_hash_find (s1set->vars, dv);
	  if (svar)
	    {
	      if (svar->n_var_parts == 1)
		{
		  VALUE_RECURSED_INTO (s1node->loc) = true;
		  intersect_loc_chains (val, dest, dsm,
					svar->var_part[0].loc_chain,
					s2var);
		  VALUE_RECURSED_INTO (s1node->loc) = false;
		}
	    }
	}

      /* ??? gotta look in cselib_val locations too.  */

      /* ??? if the location is equivalent to any location in src,
	 searched recursively

	   add to dst the values needed to represent the equivalence

     telling whether locations S is equivalent to another dv's
     location list:

       for each location D in the list

         if S and D satisfy rtx_equal_p, then it is present

	 else if D is a value, recurse without cycles

	 else if S and D have the same CODE and MODE

	   for each operand oS and the corresponding oD

	     if oS and oD are not equivalent, then S an D are not equivalent

	     else if they are RTX vectors

	       if any vector oS element is not equivalent to its respective oD,
	       then S and D are not equivalent

   */


    }
}

/* Return -1 if X should be before Y in a location list for a 1-part
   variable, 1 if Y should be before X, and 0 if they're equivalent
   and should not appear in the list.  */

static int
loc_cmp (rtx x, rtx y)
{
  int i, j, r;
  RTX_CODE code = GET_CODE (x);
  const char *fmt;

  if (x == y)
    return 0;

  if (REG_P (x))
    {
      if (!REG_P (y))
	return -1;
      gcc_assert (GET_MODE (x) == GET_MODE (y));
      if (REGNO (x) == REGNO (y))
	return 0;
      else if (REGNO (x) < REGNO (y))
	return -1;
      else
	return 1;
    }

  if (REG_P (y))
    return 1;

  if (MEM_P (x))
    {
      if (!MEM_P (y))
	return -1;
      gcc_assert (GET_MODE (x) == GET_MODE (y));
      return loc_cmp (XEXP (x, 0), XEXP (y, 0));
    }

  if (MEM_P (y))
    return 1;

  if (GET_CODE (x) == VALUE)
    {
      if (GET_CODE (y) != VALUE)
	return -1;
      /* Don't assert the modes are the same, that is true only
	 when not recursing.  (subreg:QI (value:SI 1:1) 0)
	 and (subreg:QI (value:DI 2:2) 0) can be compared,
	 even when the modes are different.  */
      if (canon_value_cmp (x, y))
	return -1;
      else
	return 1;
    }

  if (GET_CODE (y) == VALUE)
    return 1;

  /* Entry value is the least preferable kind of expression.  */
  if (GET_CODE (x) == ENTRY_VALUE)
    {
      if (GET_CODE (y) != ENTRY_VALUE)
	return 1;
      gcc_assert (GET_MODE (x) == GET_MODE (y));
      return loc_cmp (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y));
    }

  if (GET_CODE (y) == ENTRY_VALUE)
    return -1;

  if (GET_CODE (x) == GET_CODE (y))
    /* Compare operands below.  */;
  else if (GET_CODE (x) < GET_CODE (y))
    return -1;
  else
    return 1;

  gcc_assert (GET_MODE (x) == GET_MODE (y));

  if (GET_CODE (x) == DEBUG_EXPR)
    {
      if (DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x))
	  < DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (y)))
	return -1;
      gcc_checking_assert (DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x))
			   > DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (y)));
      return 1;
    }

  fmt = GET_RTX_FORMAT (code);
  for (i = 0; i < GET_RTX_LENGTH (code); i++)
    switch (fmt[i])
      {
      case 'w':
	if (XWINT (x, i) == XWINT (y, i))
	  break;
	else if (XWINT (x, i) < XWINT (y, i))
	  return -1;
	else
	  return 1;

      case 'n':
      case 'i':
	if (XINT (x, i) == XINT (y, i))
	  break;
	else if (XINT (x, i) < XINT (y, i))
	  return -1;
	else
	  return 1;

      case 'p':
	r = compare_sizes_for_sort (SUBREG_BYTE (x), SUBREG_BYTE (y));
	if (r != 0)
	  return r;
	break;

      case 'V':
      case 'E':
	/* Compare the vector length first.  */
	if (XVECLEN (x, i) == XVECLEN (y, i))
	  /* Compare the vectors elements.  */;
	else if (XVECLEN (x, i) < XVECLEN (y, i))
	  return -1;
	else
	  return 1;

	for (j = 0; j < XVECLEN (x, i); j++)
	  if ((r = loc_cmp (XVECEXP (x, i, j),
			    XVECEXP (y, i, j))))
	    return r;
	break;

      case 'e':
	if ((r = loc_cmp (XEXP (x, i), XEXP (y, i))))
	  return r;
	break;

      case 'S':
      case 's':
	if (XSTR (x, i) == XSTR (y, i))
	  break;
	if (!XSTR (x, i))
	  return -1;
	if (!XSTR (y, i))
	  return 1;
	if ((r = strcmp (XSTR (x, i), XSTR (y, i))) == 0)
	  break;
	else if (r < 0)
	  return -1;
	else
	  return 1;

      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 ();
      }
  if (CONST_WIDE_INT_P (x))
    {
      /* Compare the vector length first.  */
      if (CONST_WIDE_INT_NUNITS (x) >= CONST_WIDE_INT_NUNITS (y))
	return 1;
      else if (CONST_WIDE_INT_NUNITS (x) < CONST_WIDE_INT_NUNITS (y))
	return -1;

      /* Compare the vectors elements.  */;
      for (j = CONST_WIDE_INT_NUNITS (x) - 1; j >= 0 ; j--)
	{
	  if (CONST_WIDE_INT_ELT (x, j) < CONST_WIDE_INT_ELT (y, j))
	    return -1;
	  if (CONST_WIDE_INT_ELT (x, j) > CONST_WIDE_INT_ELT (y, j))
	    return 1;
	}
    }

  return 0;
}

/* Check the order of entries in one-part variables.   */

int
canonicalize_loc_order_check (variable **slot,
			      dataflow_set *data ATTRIBUTE_UNUSED)
{
  variable *var = *slot;
  location_chain *node, *next;

#ifdef ENABLE_RTL_CHECKING
  int i;
  for (i = 0; i < var->n_var_parts; i++)
    gcc_assert (var->var_part[0].cur_loc == NULL);
  gcc_assert (!var->in_changed_variables);
#endif

  if (!var->onepart)
    return 1;

  gcc_assert (var->n_var_parts == 1);
  node = var->var_part[0].loc_chain;
  gcc_assert (node);

  while ((next = node->next))
    {
      gcc_assert (loc_cmp (node->loc, next->loc) < 0);
      node = next;
    }

  return 1;
}

/* Mark with VALUE_RECURSED_INTO values that have neighbors that are
   more likely to be chosen as canonical for an equivalence set.
   Ensure less likely values can reach more likely neighbors, making
   the connections bidirectional.  */

int
canonicalize_values_mark (variable **slot, dataflow_set *set)
{
  variable *var = *slot;
  decl_or_value dv = var->dv;
  rtx val;
  location_chain *node;

  if (!dv_is_value_p (dv))
    return 1;

  gcc_checking_assert (var->n_var_parts == 1);

  val = dv_as_value (dv);

  for (node = var->var_part[0].loc_chain; node; node = node->next)
    if (GET_CODE (node->loc) == VALUE)
      {
	if (canon_value_cmp (node->loc, val))
	  VALUE_RECURSED_INTO (val) = true;
	else
	  {
	    decl_or_value odv = dv_from_value (node->loc);
	    variable **oslot;
	    oslot = shared_hash_find_slot_noinsert (set->vars, odv);

	    set_slot_part (set, val, oslot, odv, 0,
			   node->init, NULL_RTX);

	    VALUE_RECURSED_INTO (node->loc) = true;
	  }
      }

  return 1;
}

/* Remove redundant entries from equivalence lists in onepart
   variables, canonicalizing equivalence sets into star shapes.  */

int
canonicalize_values_star (variable **slot, dataflow_set *set)
{
  variable *var = *slot;
  decl_or_value dv = var->dv;
  location_chain *node;
  decl_or_value cdv;
  rtx val, cval;
  variable **cslot;
  bool has_value;
  bool has_marks;

  if (!var->onepart)
    return 1;

  gcc_checking_assert (var->n_var_parts == 1);

  if (dv_is_value_p (dv))
    {
      cval = dv_as_value (dv);
      if (!VALUE_RECURSED_INTO (cval))
	return 1;
      VALUE_RECURSED_INTO (cval) = false;
    }
  else
    cval = NULL_RTX;

 restart:
  val = cval;
  has_value = false;
  has_marks = false;

  gcc_assert (var->n_var_parts == 1);

  for (node = var->var_part[0].loc_chain; node; node = node->next)
    if (GET_CODE (node->loc) == VALUE)
      {
	has_value = true;
	if (VALUE_RECURSED_INTO (node->loc))
	  has_marks = true;
	if (canon_value_cmp (node->loc, cval))
	  cval = node->loc;
      }

  if (!has_value)
    return 1;

  if (cval == val)
    {
      if (!has_marks || dv_is_decl_p (dv))
	return 1;

      /* Keep it marked so that we revisit it, either after visiting a
	 child node, or after visiting a new parent that might be
	 found out.  */
      VALUE_RECURSED_INTO (val) = true;

      for (node = var->var_part[0].loc_chain; node; node = node->next)
	if (GET_CODE (node->loc) == VALUE
	    && VALUE_RECURSED_INTO (node->loc))
	  {
	    cval = node->loc;
	  restart_with_cval:
	    VALUE_RECURSED_INTO (cval) = false;
	    dv = dv_from_value (cval);
	    slot = shared_hash_find_slot_noinsert (set->vars, dv);
	    if (!slot)
	      {
		gcc_assert (dv_is_decl_p (var->dv));
		/* The canonical value was reset and dropped.
		   Remove it.  */
		clobber_variable_part (set, NULL, var->dv, 0, NULL);
		return 1;
	      }
	    var = *slot;
	    gcc_assert (dv_is_value_p (var->dv));
	    if (var->n_var_parts == 0)
	      return 1;
	    gcc_assert (var->n_var_parts == 1);
	    goto restart;
	  }

      VALUE_RECURSED_INTO (val) = false;

      return 1;
    }

  /* Push values to the canonical one.  */
  cdv = dv_from_value (cval);
  cslot = shared_hash_find_slot_noinsert (set->vars, cdv);

  for (node = var->var_part[0].loc_chain; node; node = node->next)
    if (node->loc != cval)
      {
	cslot = set_slot_part (set, node->loc, cslot, cdv, 0,
			       node->init, NULL_RTX);
	if (GET_CODE (node->loc) == VALUE)
	  {
	    decl_or_value ndv = dv_from_value (node->loc);

	    set_variable_part (set, cval, ndv, 0, node->init, NULL_RTX,
			       NO_INSERT);

	    if (canon_value_cmp (node->loc, val))
	      {
		/* If it could have been a local minimum, it's not any more,
		   since it's now neighbor to cval, so it may have to push
		   to it.  Conversely, if it wouldn't have prevailed over
		   val, then whatever mark it has is fine: if it was to
		   push, it will now push to a more canonical node, but if
		   it wasn't, then it has already pushed any values it might
		   have to.  */
		VALUE_RECURSED_INTO (node->loc) = true;
		/* Make sure we visit node->loc by ensuring we cval is
		   visited too.  */
		VALUE_RECURSED_INTO (cval) = true;
	      }
	    else if (!VALUE_RECURSED_INTO (node->loc))
	      /* If we have no need to "recurse" into this node, it's
		 already "canonicalized", so drop the link to the old
		 parent.  */
	      clobber_variable_part (set, cval, ndv, 0, NULL);
	  }
	else if (GET_CODE (node->loc) == REG)
	  {
	    attrs *list = set->regs[REGNO (node->loc)], **listp;

	    /* Change an existing attribute referring to dv so that it
	       refers to cdv, removing any duplicate this might
	       introduce, and checking that no previous duplicates
	       existed, all in a single pass.  */

	    while (list)
	      {
		if (list->offset == 0
		    && (dv_as_opaque (list->dv) == dv_as_opaque (dv)
			|| dv_as_opaque (list->dv) == dv_as_opaque (cdv)))
		  break;

		list = list->next;
	      }

	    gcc_assert (list);
	    if (dv_as_opaque (list->dv) == dv_as_opaque (dv))
	      {
		list->dv = cdv;
		for (listp = &list->next; (list = *listp); listp = &list->next)
		  {
		    if (list->offset)
		      continue;

		    if (dv_as_opaque (list->dv) == dv_as_opaque (cdv))
		      {
			*listp = list->next;
			delete list;
			list = *listp;
			break;
		      }

		    gcc_assert (dv_as_opaque (list->dv) != dv_as_opaque (dv));
		  }
	      }
	    else if (dv_as_opaque (list->dv) == dv_as_opaque (cdv))
	      {
		for (listp = &list->next; (list = *listp); listp = &list->next)
		  {
		    if (list->offset)
		      continue;

		    if (dv_as_opaque (list->dv) == dv_as_opaque (dv))
		      {
			*listp = list->next;
			delete list;
			list = *listp;
			break;
		      }

		    gcc_assert (dv_as_opaque (list->dv) != dv_as_opaque (cdv));
		  }
	      }
	    else
	      gcc_unreachable ();

	    if (flag_checking)
	      while (list)
		{
		  if (list->offset == 0
		      && (dv_as_opaque (list->dv) == dv_as_opaque (dv)
			  || dv_as_opaque (list->dv) == dv_as_opaque (cdv)))
		    gcc_unreachable ();

		  list = list->next;
		}
	  }
      }

  if (val)
    set_slot_part (set, val, cslot, cdv, 0,
		   VAR_INIT_STATUS_INITIALIZED, NULL_RTX);

  slot = clobber_slot_part (set, cval, slot, 0, NULL);

  /* Variable may have been unshared.  */
  var = *slot;
  gcc_checking_assert (var->n_var_parts && var->var_part[0].loc_chain->loc == cval
		       && var->var_part[0].loc_chain->next == NULL);

  if (VALUE_RECURSED_INTO (cval))
    goto restart_with_cval;

  return 1;
}

/* Bind one-part variables to the canonical value in an equivalence
   set.  Not doing this causes dataflow convergence failure in rare
   circumstances, see PR42873.  Unfortunately we can't do this
   efficiently as part of canonicalize_values_star, since we may not
   have determined or even seen the canonical value of a set when we
   get to a variable that references another member of the set.  */

int
canonicalize_vars_star (variable **slot, dataflow_set *set)
{
  variable *var = *slot;
  decl_or_value dv = var->dv;
  location_chain *node;
  rtx cval;
  decl_or_value cdv;
  variable **cslot;
  variable *cvar;
  location_chain *cnode;

  if (!var->onepart || var->onepart == ONEPART_VALUE)
    return 1;

  gcc_assert (var->n_var_parts == 1);

  node = var->var_part[0].loc_chain;

  if (GET_CODE (node->loc) != VALUE)
    return 1;

  gcc_assert (!node->next);
  cval = node->loc;

  /* Push values to the canonical one.  */
  cdv = dv_from_value (cval);
  cslot = shared_hash_find_slot_noinsert (set->vars, cdv);
  if (!cslot)
    return 1;
  cvar = *cslot;
  gcc_assert (cvar->n_var_parts == 1);

  cnode = cvar->var_part[0].loc_chain;

  /* CVAL is canonical if its value list contains non-VALUEs or VALUEs
     that are not “more canonical” than it.  */
  if (GET_CODE (cnode->loc) != VALUE
      || !canon_value_cmp (cnode->loc, cval))
    return 1;

  /* CVAL was found to be non-canonical.  Change the variable to point
     to the canonical VALUE.  */
  gcc_assert (!cnode->next);
  cval = cnode->loc;

  slot = set_slot_part (set, cval, slot, dv, 0,
			node->init, node->set_src);
  clobber_slot_part (set, cval, slot, 0, node->set_src);

  return 1;
}

/* Combine variable or value in *S1SLOT (in DSM->cur) with the
   corresponding entry in DSM->src.  Multi-part variables are combined
   with variable_union, whereas onepart dvs are combined with
   intersection.  */

static int
variable_merge_over_cur (variable *s1var, struct dfset_merge *dsm)
{
  dataflow_set *dst = dsm->dst;
  variable **dstslot;
  variable *s2var, *dvar = NULL;
  decl_or_value dv = s1var->dv;
  onepart_enum onepart = s1var->onepart;
  rtx val;
  hashval_t dvhash;
  location_chain *node, **nodep;

  /* If the incoming onepart variable has an empty location list, then
     the intersection will be just as empty.  For other variables,
     it's always union.  */
  gcc_checking_assert (s1var->n_var_parts
		       && s1var->var_part[0].loc_chain);

  if (!onepart)
    return variable_union (s1var, dst);

  gcc_checking_assert (s1var->n_var_parts == 1);

  dvhash = dv_htab_hash (dv);
  if (dv_is_value_p (dv))
    val = dv_as_value (dv);
  else
    val = NULL;

  s2var = shared_hash_find_1 (dsm->src->vars, dv, dvhash);
  if (!s2var)
    {
      dst_can_be_shared = false;
      return 1;
    }

  dsm->src_onepart_cnt--;
  gcc_assert (s2var->var_part[0].loc_chain
	      && s2var->onepart == onepart
	      && s2var->n_var_parts == 1);

  dstslot = shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash);
  if (dstslot)
    {
      dvar = *dstslot;
      gcc_assert (dvar->refcount == 1
		  && dvar->onepart == onepart
		  && dvar->n_var_parts == 1);
      nodep = &dvar->var_part[0].loc_chain;
    }
  else
    {
      nodep = &node;
      node = NULL;
    }

  if (!dstslot && !onepart_variable_different_p (s1var, s2var))
    {
      dstslot = shared_hash_find_slot_unshare_1 (&dst->vars, dv,
						 dvhash, INSERT);
      *dstslot = dvar = s2var;
      dvar->refcount++;
    }
  else
    {
      dst_can_be_shared = false;

      intersect_loc_chains (val, nodep, dsm,
			    s1var->var_part[0].loc_chain, s2var);

      if (!dstslot)
	{
	  if (node)
	    {
	      dvar = onepart_pool_allocate (onepart);
	      dvar->dv = dv;
	      dvar->refcount = 1;
	      dvar->n_var_parts = 1;
	      dvar->onepart = onepart;
	      dvar->in_changed_variables = false;
	      dvar->var_part[0].loc_chain = node;
	      dvar->var_part[0].cur_loc = NULL;
	      if (onepart)
		VAR_LOC_1PAUX (dvar) = NULL;
	      else
		VAR_PART_OFFSET (dvar, 0) = 0;

	      dstslot
		= shared_hash_find_slot_unshare_1 (&dst->vars, dv, dvhash,
						   INSERT);
	      gcc_assert (!*dstslot);
	      *dstslot = dvar;
	    }
	  else
	    return 1;
	}
    }

  nodep = &dvar->var_part[0].loc_chain;
  while ((node = *nodep))
    {
      location_chain **nextp = &node->next;

      if (GET_CODE (node->loc) == REG)
	{
	  attrs *list;

	  for (list = dst->regs[REGNO (node->loc)]; list; list = list->next)
	    if (GET_MODE (node->loc) == GET_MODE (list->loc)
		&& dv_is_value_p (list->dv))
	      break;

	  if (!list)
	    attrs_list_insert (&dst->regs[REGNO (node->loc)],
			       dv, 0, node->loc);
	  /* If this value became canonical for another value that had
	     this register, we want to leave it alone.  */
	  else if (dv_as_value (list->dv) != val)
	    {
	      dstslot = set_slot_part (dst, dv_as_value (list->dv),
				       dstslot, dv, 0,
				       node->init, NULL_RTX);
	      dstslot = delete_slot_part (dst, node->loc, dstslot, 0);

	      /* Since nextp points into the removed node, we can't
		 use it.  The pointer to the next node moved to nodep.
		 However, if the variable we're walking is unshared
		 during our walk, we'll keep walking the location list
		 of the previously-shared variable, in which case the
		 node won't have been removed, and we'll want to skip
		 it.  That's why we test *nodep here.  */
	      if (*nodep != node)
		nextp = nodep;
	    }
	}
      else
	/* Canonicalization puts registers first, so we don't have to
	   walk it all.  */
	break;
      nodep = nextp;
    }

  if (dvar != *dstslot)
    dvar = *dstslot;
  nodep = &dvar->var_part[0].loc_chain;

  if (val)
    {
      /* Mark all referenced nodes for canonicalization, and make sure
	 we have mutual equivalence links.  */
      VALUE_RECURSED_INTO (val) = true;
      for (node = *nodep; node; node = node->next)
	if (GET_CODE (node->loc) == VALUE)
	  {
	    VALUE_RECURSED_INTO (node->loc) = true;
	    set_variable_part (dst, val, dv_from_value (node->loc), 0,
			       node->init, NULL, INSERT);
	  }

      dstslot = shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash);
      gcc_assert (*dstslot == dvar);
      canonicalize_values_star (dstslot, dst);
      gcc_checking_assert (dstslot
			   == shared_hash_find_slot_noinsert_1 (dst->vars,
								dv, dvhash));
      dvar = *dstslot;
    }
  else
    {
      bool has_value = false, has_other = false;

      /* If we have one value and anything else, we're going to
	 canonicalize this, so make sure all values have an entry in
	 the table and are marked for canonicalization.  */
      for (node = *nodep; node; node = node->next)
	{
	  if (GET_CODE (node->loc) == VALUE)
	    {
	      /* If this was marked during register canonicalization,
		 we know we have to canonicalize values.  */
	      if (has_value)
		has_other = true;
	      has_value = true;
	      if (has_other)
		break;
	    }
	  else
	    {
	      has_other = true;
	      if (has_value)
		break;
	    }
	}

      if (has_value && has_other)
	{
	  for (node = *nodep; node; node = node->next)
	    {
	      if (GET_CODE (node->loc) == VALUE)
		{
		  decl_or_value dv = dv_from_value (node->loc);
		  variable **slot = NULL;

		  if (shared_hash_shared (dst->vars))
		    slot = shared_hash_find_slot_noinsert (dst->vars, dv);
		  if (!slot)
		    slot = shared_hash_find_slot_unshare (&dst->vars, dv,
							  INSERT);
		  if (!*slot)
		    {
		      variable *var = onepart_pool_allocate (ONEPART_VALUE);
		      var->dv = dv;
		      var->refcount = 1;
		      var->n_var_parts = 1;
		      var->onepart = ONEPART_VALUE;
		      var->in_changed_variables = false;
		      var->var_part[0].loc_chain = NULL;
		      var->var_part[0].cur_loc = NULL;
		      VAR_LOC_1PAUX (var) = NULL;
		      *slot = var;
		    }

		  VALUE_RECURSED_INTO (node->loc) = true;
		}
	    }

	  dstslot = shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash);
	  gcc_assert (*dstslot == dvar);
	  canonicalize_values_star (dstslot, dst);
	  gcc_checking_assert (dstslot
			       == shared_hash_find_slot_noinsert_1 (dst->vars,
								    dv, dvhash));
	  dvar = *dstslot;
	}
    }

  if (!onepart_variable_different_p (dvar, s2var))
    {
      variable_htab_free (dvar);
      *dstslot = dvar = s2var;
      dvar->refcount++;
    }
  else if (s2var != s1var && !onepart_variable_different_p (dvar, s1var))
    {
      variable_htab_free (dvar);
      *dstslot = dvar = s1var;
      dvar->refcount++;
      dst_can_be_shared = false;
    }
  else
    dst_can_be_shared = false;

  return 1;
}

/* Copy s2slot (in DSM->src) to DSM->dst if the variable is a
   multi-part variable.  Unions of multi-part variables and
   intersections of one-part ones will be handled in
   variable_merge_over_cur().  */

static int
variable_merge_over_src (variable *s2var, struct dfset_merge *dsm)
{
  dataflow_set *dst = dsm->dst;
  decl_or_value dv = s2var->dv;

  if (!s2var->onepart)
    {
      variable **dstp = shared_hash_find_slot (dst->vars, dv);
      *dstp = s2var;
      s2var->refcount++;
      return 1;
    }

  dsm->src_onepart_cnt++;
  return 1;
}

/* Combine dataflow set information from SRC2 into DST, using PDST
   to carry over information across passes.  */

static void
dataflow_set_merge (dataflow_set *dst, dataflow_set *src2)
{
  dataflow_set cur = *dst;
  dataflow_set *src1 = &cur;
  struct dfset_merge dsm;
  int i;
  size_t src1_elems, src2_elems;
  variable_iterator_type hi;
  variable *var;

  src1_elems = shared_hash_htab (src1->vars)->elements ();
  src2_elems = shared_hash_htab (src2->vars)->elements ();
  dataflow_set_init (dst);
  dst->stack_adjust = cur.stack_adjust;
  shared_hash_destroy (dst->vars);
  dst->vars = new shared_hash;
  dst->vars->refcount = 1;
  dst->vars->htab = new variable_table_type (MAX (src1_elems, src2_elems));

  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    attrs_list_mpdv_union (&dst->regs[i], src1->regs[i], src2->regs[i]);

  dsm.dst = dst;
  dsm.src = src2;
  dsm.cur = src1;
  dsm.src_onepart_cnt = 0;

  FOR_EACH_HASH_TABLE_ELEMENT (*shared_hash_htab (dsm.src->vars),
			       var, variable, hi)
    variable_merge_over_src (var, &dsm);
  FOR_EACH_HASH_TABLE_ELEMENT (*shared_hash_htab (dsm.cur->vars),
			       var, variable, hi)
    variable_merge_over_cur (var, &dsm);

  if (dsm.src_onepart_cnt)
    dst_can_be_shared = false;

  dataflow_set_destroy (src1);
}

/* Mark register equivalences.  */

static void
dataflow_set_equiv_regs (dataflow_set *set)
{
  int i;
  attrs *list, **listp;

  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    {
      rtx canon[NUM_MACHINE_MODES];

      /* If the list is empty or one entry, no need to canonicalize
	 anything.  */
      if (set->regs[i] == NULL || set->regs[i]->next == NULL)
	continue;

      memset (canon, 0, sizeof (canon));

      for (list = set->regs[i]; list; list = list->next)
	if (list->offset == 0 && dv_is_value_p (list->dv))
	  {
	    rtx val = dv_as_value (list->dv);
	    rtx *cvalp = &canon[(int)GET_MODE (val)];
	    rtx cval = *cvalp;

	    if (canon_value_cmp (val, cval))
	      *cvalp = val;
	  }

      for (list = set->regs[i]; list; list = list->next)
	if (list->offset == 0 && dv_onepart_p (list->dv))
	  {
	    rtx cval = canon[(int)GET_MODE (list->loc)];

	    if (!cval)
	      continue;

	    if (dv_is_value_p (list->dv))
	      {
		rtx val = dv_as_value (list->dv);

		if (val == cval)
		  continue;

		VALUE_RECURSED_INTO (val) = true;
		set_variable_part (set, val, dv_from_value (cval), 0,
				   VAR_INIT_STATUS_INITIALIZED,
				   NULL, NO_INSERT);
	      }

	    VALUE_RECURSED_INTO (cval) = true;
	    set_variable_part (set, cval, list->dv, 0,
			       VAR_INIT_STATUS_INITIALIZED, NULL, NO_INSERT);
	  }

      for (listp = &set->regs[i]; (list = *listp);
	   listp = list ? &list->next : listp)
	if (list->offset == 0 && dv_onepart_p (list->dv))
	  {
	    rtx cval = canon[(int)GET_MODE (list->loc)];
	    variable **slot;

	    if (!cval)
	      continue;

	    if (dv_is_value_p (list->dv))
	      {
		rtx val = dv_as_value (list->dv);
		if (!VALUE_RECURSED_INTO (val))
		  continue;
	      }

	    slot = shared_hash_find_slot_noinsert (set->vars, list->dv);
	    canonicalize_values_star (slot, set);
	    if (*listp != list)
	      list = NULL;
	  }
    }
}

/* Remove any redundant values in the location list of VAR, which must
   be unshared and 1-part.  */

static void
remove_duplicate_values (variable *var)
{
  location_chain *node, **nodep;

  gcc_assert (var->onepart);
  gcc_assert (var->n_var_parts == 1);
  gcc_assert (var->refcount == 1);

  for (nodep = &var->var_part[0].loc_chain; (node = *nodep); )
    {
      if (GET_CODE (node->loc) == VALUE)
	{
	  if (VALUE_RECURSED_INTO (node->loc))
	    {
	      /* Remove duplicate value node.  */
	      *nodep = node->next;
	      delete node;
	      continue;
	    }
	  else
	    VALUE_RECURSED_INTO (node->loc) = true;
	}
      nodep = &node->next;
    }

  for (node = var->var_part[0].loc_chain; node; node = node->next)
    if (GET_CODE (node->loc) == VALUE)
      {
	gcc_assert (VALUE_RECURSED_INTO (node->loc));
	VALUE_RECURSED_INTO (node->loc) = false;
      }
}


/* Hash table iteration argument passed to variable_post_merge.  */
struct dfset_post_merge
{
  /* The new input set for the current block.  */
  dataflow_set *set;
  /* Pointer to the permanent input set for the current block, or
     NULL.  */
  dataflow_set **permp;
};

/* Create values for incoming expressions associated with one-part
   variables that don't have value numbers for them.  */

int
variable_post_merge_new_vals (variable **slot, dfset_post_merge *dfpm)
{
  dataflow_set *set = dfpm->set;
  variable *var = *slot;
  location_chain *node;

  if (!var->onepart || !var->n_var_parts)
    return 1;

  gcc_assert (var->n_var_parts == 1);

  if (dv_is_decl_p (var->dv))
    {
      bool check_dupes = false;

    restart:
      for (node = var->var_part[0].loc_chain; node; node = node->next)
	{
	  if (GET_CODE (node->loc) == VALUE)
	    gcc_assert (!VALUE_RECURSED_INTO (node->loc));
	  else if (GET_CODE (node->loc) == REG)
	    {
	      attrs *att, **attp, **curp = NULL;

	      if (var->refcount != 1)
		{
		  slot = unshare_variable (set, slot, var,
					   VAR_INIT_STATUS_INITIALIZED);
		  var = *slot;
		  goto restart;
		}

	      for (attp = &set->regs[REGNO (node->loc)]; (att = *attp);
		   attp = &att->next)
		if (att->offset == 0
		    && GET_MODE (att->loc) == GET_MODE (node->loc))
		  {
		    if (dv_is_value_p (att->dv))
		      {
			rtx cval = dv_as_value (att->dv);
			node->loc = cval;
			check_dupes = true;
			break;
		      }
		    else if (dv_as_opaque (att->dv) == dv_as_opaque (var->dv))
		      curp = attp;
		  }

	      if (!curp)
		{
		  curp = attp;
		  while (*curp)
		    if ((*curp)->offset == 0
			&& GET_MODE ((*curp)->loc) == GET_MODE (node->loc)
			&& dv_as_opaque ((*curp)->dv) == dv_as_opaque (var->dv))
		      break;
		    else
		      curp = &(*curp)->next;
		  gcc_assert (*curp);
		}

	      if (!att)
		{
		  decl_or_value cdv;
		  rtx cval;

		  if (!*dfpm->permp)
		    {
		      *dfpm->permp = XNEW (dataflow_set);
		      dataflow_set_init (*dfpm->permp);
		    }

		  for (att = (*dfpm->permp)->regs[REGNO (node->loc)];
		       att; att = att->next)
		    if (GET_MODE (att->loc) == GET_MODE (node->loc))
		      {
			gcc_assert (att->offset == 0
				    && dv_is_value_p (att->dv));
			val_reset (set, att->dv);
			break;
		      }

		  if (att)
		    {
		      cdv = att->dv;
		      cval = dv_as_value (cdv);
		    }
		  else
		    {
		      /* Create a unique value to hold this register,
			 that ought to be found and reused in
			 subsequent rounds.  */
		      cselib_val *v;
		      gcc_assert (!cselib_lookup (node->loc,
						  GET_MODE (node->loc), 0,
						  VOIDmode));
		      v = cselib_lookup (node->loc, GET_MODE (node->loc), 1,
					 VOIDmode);
		      cselib_preserve_value (v);
		      cselib_invalidate_rtx (node->loc);
		      cval = v->val_rtx;
		      cdv = dv_from_value (cval);
		      if (dump_file)
			fprintf (dump_file,
				 "Created new value %u:%u for reg %i\n",
				 v->uid, v->hash, REGNO (node->loc));
		    }

		  var_reg_decl_set (*dfpm->permp, node->loc,
				    VAR_INIT_STATUS_INITIALIZED,
				    cdv, 0, NULL, INSERT);

		  node->loc = cval;
		  check_dupes = true;
		}

	      /* Remove attribute referring to the decl, which now
		 uses the value for the register, already existing or
		 to be added when we bring perm in.  */
	      att = *curp;
	      *curp = att->next;
	      delete att;
	    }
	}

      if (check_dupes)
	remove_duplicate_values (var);
    }

  return 1;
}

/* Reset values in the permanent set that are not associated with the
   chosen expression.  */

int
variable_post_merge_perm_vals (variable **pslot, dfset_post_merge *dfpm)
{
  dataflow_set *set = dfpm->set;
  variable *pvar = *pslot, *var;
  location_chain *pnode;
  decl_or_value dv;
  attrs *att;

  gcc_assert (dv_is_value_p (pvar->dv)
	      && pvar->n_var_parts == 1);
  pnode = pvar->var_part[0].loc_chain;
  gcc_assert (pnode
	      && !pnode->next
	      && REG_P (pnode->loc));

  dv = pvar->dv;

  var = shared_hash_find (set->vars, dv);
  if (var)
    {
      /* Although variable_post_merge_new_vals may have made decls
	 non-star-canonical, values that pre-existed in canonical form
	 remain canonical, and newly-created values reference a single
	 REG, so they are canonical as well.  Since VAR has the
	 location list for a VALUE, using find_loc_in_1pdv for it is
	 fine, since VALUEs don't map back to DECLs.  */
      if (find_loc_in_1pdv (pnode->loc, var, shared_hash_htab (set->vars)))
	return 1;
      val_reset (set, dv);
    }

  for (att = set->regs[REGNO (pnode->loc)]; att; att = att->next)
    if (att->offset == 0
	&& GET_MODE (att->loc) == GET_MODE (pnode->loc)
	&& dv_is_value_p (att->dv))
      break;

  /* If there is a value associated with this register already, create
     an equivalence.  */
  if (att && dv_as_value (att->dv) != dv_as_value (dv))
    {
      rtx cval = dv_as_value (att->dv);
      set_variable_part (set, cval, dv, 0, pnode->init, NULL, INSERT);
      set_variable_part (set, dv_as_value (dv), att->dv, 0, pnode->init,
			 NULL, INSERT);
    }
  else if (!att)
    {
      attrs_list_insert (&set->regs[REGNO (pnode->loc)],
			 dv, 0, pnode->loc);
      variable_union (pvar, set);
    }

  return 1;
}

/* Just checking stuff and registering register attributes for
   now.  */

static void
dataflow_post_merge_adjust (dataflow_set *set, dataflow_set **permp)
{
  struct dfset_post_merge dfpm;

  dfpm.set = set;
  dfpm.permp = permp;

  shared_hash_htab (set->vars)
    ->traverse <dfset_post_merge*, variable_post_merge_new_vals> (&dfpm);
  if (*permp)
    shared_hash_htab ((*permp)->vars)
      ->traverse <dfset_post_merge*, variable_post_merge_perm_vals> (&dfpm);
  shared_hash_htab (set->vars)
    ->traverse <dataflow_set *, canonicalize_values_star> (set);
  shared_hash_htab (set->vars)
    ->traverse <dataflow_set *, canonicalize_vars_star> (set);
}

/* Return a node whose loc is a MEM that refers to EXPR in the
   location list of a one-part variable or value VAR, or in that of
   any values recursively mentioned in the location lists.  */

static location_chain *
find_mem_expr_in_1pdv (tree expr, rtx val, variable_table_type *vars)
{
  location_chain *node;
  decl_or_value dv;
  variable *var;
  location_chain *where = NULL;

  if (!val)
    return NULL;

  gcc_assert (GET_CODE (val) == VALUE
	      && !VALUE_RECURSED_INTO (val));

  dv = dv_from_value (val);
  var = vars->find_with_hash (dv, dv_htab_hash (dv));

  if (!var)
    return NULL;

  gcc_assert (var->onepart);

  if (!var->n_var_parts)
    return NULL;

  VALUE_RECURSED_INTO (val) = true;

  for (node = var->var_part[0].loc_chain; node; node = node->next)
    if (MEM_P (node->loc)
	&& MEM_EXPR (node->loc) == expr
	&& int_mem_offset (node->loc) == 0)
      {
	where = node;
	break;
      }
    else if (GET_CODE (node->loc) == VALUE
	     && !VALUE_RECURSED_INTO (node->loc)
	     && (where = find_mem_expr_in_1pdv (expr, node->loc, vars)))
      break;

  VALUE_RECURSED_INTO (val) = false;

  return where;
}

/* Return TRUE if the value of MEM may vary across a call.  */

static bool
mem_dies_at_call (rtx mem)
{
  tree expr = MEM_EXPR (mem);
  tree decl;

  if (!expr)
    return true;

  decl = get_base_address (expr);

  if (!decl)
    return true;

  if (!DECL_P (decl))
    return true;

  return (may_be_aliased (decl)
	  || (!TREE_READONLY (decl) && is_global_var (decl)));
}

/* Remove all MEMs from the location list of a hash table entry for a
   one-part variable, except those whose MEM attributes map back to
   the variable itself, directly or within a VALUE.  */

int
dataflow_set_preserve_mem_locs (variable **slot, dataflow_set *set)
{
  variable *var = *slot;

  if (var->onepart == ONEPART_VDECL || var->onepart == ONEPART_DEXPR)
    {
      tree decl = dv_as_decl (var->dv);
      location_chain *loc, **locp;
      bool changed = false;

      if (!var->n_var_parts)
	return 1;

      gcc_assert (var->n_var_parts == 1);

      if (shared_var_p (var, set->vars))
	{
	  for (loc = var->var_part[0].loc_chain; loc; loc = loc->next)
	    {
	      /* We want to remove dying MEMs that don't refer to DECL.  */
	      if (GET_CODE (loc->loc) == MEM
		  && (MEM_EXPR (loc->loc) != decl
		      || int_mem_offset (loc->loc) != 0)
		  && mem_dies_at_call (loc->loc))
		break;
	      /* We want to move here MEMs that do refer to DECL.  */
	      else if (GET_CODE (loc->loc) == VALUE
		       && find_mem_expr_in_1pdv (decl, loc->loc,
						 shared_hash_htab (set->vars)))
		break;
	    }

	  if (!loc)
	    return 1;

	  slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN);
	  var = *slot;
	  gcc_assert (var->n_var_parts == 1);
	}

      for (locp = &var->var_part[0].loc_chain, loc = *locp;
	   loc; loc = *locp)
	{
	  rtx old_loc = loc->loc;
	  if (GET_CODE (old_loc) == VALUE)
	    {
	      location_chain *mem_node
		= find_mem_expr_in_1pdv (decl, loc->loc,
					 shared_hash_htab (set->vars));

	      /* ??? This picks up only one out of multiple MEMs that
		 refer to the same variable.  Do we ever need to be
		 concerned about dealing with more than one, or, given
		 that they should all map to the same variable
		 location, their addresses will have been merged and
		 they will be regarded as equivalent?  */
	      if (mem_node)
		{
		  loc->loc = mem_node->loc;
		  loc->set_src = mem_node->set_src;
		  loc->init = MIN (loc->init, mem_node->init);
		}
	    }

	  if (GET_CODE (loc->loc) != MEM
	      || (MEM_EXPR (loc->loc) == decl
		  && int_mem_offset (loc->loc) == 0)
	      || !mem_dies_at_call (loc->loc))
	    {
	      if (old_loc != loc->loc && emit_notes)
		{
		  if (old_loc == var->var_part[0].cur_loc)
		    {
		      changed = true;
		      var->var_part[0].cur_loc = NULL;
		    }
		}
	      locp = &loc->next;
	      continue;
	    }

	  if (emit_notes)
	    {
	      if (old_loc == var->var_part[0].cur_loc)
		{
		  changed = true;
		  var->var_part[0].cur_loc = NULL;
		}
	    }
	  *locp = loc->next;
	  delete loc;
	}

      if (!var->var_part[0].loc_chain)
	{
	  var->n_var_parts--;
	  changed = true;
	}
      if (changed)
	variable_was_changed (var, set);
    }

  return 1;
}

/* Remove all MEMs from the location list of a hash table entry for a
   onepart variable.  */

int
dataflow_set_remove_mem_locs (variable **slot, dataflow_set *set)
{
  variable *var = *slot;

  if (var->onepart != NOT_ONEPART)
    {
      location_chain *loc, **locp;
      bool changed = false;
      rtx cur_loc;

      gcc_assert (var->n_var_parts == 1);

      if (shared_var_p (var, set->vars))
	{
	  for (loc = var->var_part[0].loc_chain; loc; loc = loc->next)
	    if (GET_CODE (loc->loc) == MEM
		&& mem_dies_at_call (loc->loc))
	      break;

	  if (!loc)
	    return 1;

	  slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN);
	  var = *slot;
	  gcc_assert (var->n_var_parts == 1);
	}

      if (VAR_LOC_1PAUX (var))
	cur_loc = VAR_LOC_FROM (var);
      else
	cur_loc = var->var_part[0].cur_loc;

      for (locp = &var->var_part[0].loc_chain, loc = *locp;
	   loc; loc = *locp)
	{
	  if (GET_CODE (loc->loc) != MEM
	      || !mem_dies_at_call (loc->loc))
	    {
	      locp = &loc->next;
	      continue;
	    }

	  *locp = loc->next;
	  /* If we have deleted the location which was last emitted
	     we have to emit new location so add the variable to set
	     of changed variables.  */
	  if (cur_loc == loc->loc)
	    {
	      changed = true;
	      var->var_part[0].cur_loc = NULL;
	      if (VAR_LOC_1PAUX (var))
		VAR_LOC_FROM (var) = NULL;
	    }
	  delete loc;
	}

      if (!var->var_part[0].loc_chain)
	{
	  var->n_var_parts--;
	  changed = true;
	}
      if (changed)
	variable_was_changed (var, set);
    }

  return 1;
}

/* Remove all variable-location information about call-clobbered
   registers, as well as associations between MEMs and VALUEs.  */

static void
dataflow_set_clear_at_call (dataflow_set *set, rtx_insn *call_insn)
{
  unsigned int r;
  hard_reg_set_iterator hrsi;

  HARD_REG_SET callee_clobbers
    = insn_callee_abi (call_insn).full_reg_clobbers ();

  EXECUTE_IF_SET_IN_HARD_REG_SET (callee_clobbers, 0, r, hrsi)
    var_regno_delete (set, r);

  if (MAY_HAVE_DEBUG_BIND_INSNS)
    {
      set->traversed_vars = set->vars;
      shared_hash_htab (set->vars)
	->traverse <dataflow_set *, dataflow_set_preserve_mem_locs> (set);
      set->traversed_vars = set->vars;
      shared_hash_htab (set->vars)
	->traverse <dataflow_set *, dataflow_set_remove_mem_locs> (set);
      set->traversed_vars = NULL;
    }
}

static bool
variable_part_different_p (variable_part *vp1, variable_part *vp2)
{
  location_chain *lc1, *lc2;

  for (lc1 = vp1->loc_chain; lc1; lc1 = lc1->next)
    {
      for (lc2 = vp2->loc_chain; lc2; lc2 = lc2->next)
	{
	  if (REG_P (lc1->loc) && REG_P (lc2->loc))
	    {
	      if (REGNO (lc1->loc) == REGNO (lc2->loc))
		break;
	    }
	  if (rtx_equal_p (lc1->loc, lc2->loc))
	    break;
	}
      if (!lc2)
	return true;
    }
  return false;
}

/* Return true if one-part variables VAR1 and VAR2 are different.
   They must be in canonical order.  */

static bool
onepart_variable_different_p (variable *var1, variable *var2)
{
  location_chain *lc1, *lc2;

  if (var1 == var2)
    return false;

  gcc_assert (var1->n_var_parts == 1
	      && var2->n_var_parts == 1);

  lc1 = var1->var_part[0].loc_chain;
  lc2 = var2->var_part[0].loc_chain;

  gcc_assert (lc1 && lc2);

  while (lc1 && lc2)
    {
      if (loc_cmp (lc1->loc, lc2->loc))
	return true;
      lc1 = lc1->next;
      lc2 = lc2->next;
    }

  return lc1 != lc2;
}

/* Return true if one-part variables VAR1 and VAR2 are different.
   They must be in canonical order.  */

static void
dump_onepart_variable_differences (variable *var1, variable *var2)
{
  location_chain *lc1, *lc2;

  gcc_assert (var1 != var2);
  gcc_assert (dump_file);
  gcc_assert (dv_as_opaque (var1->dv) == dv_as_opaque (var2->dv));
  gcc_assert (var1->n_var_parts == 1
	      && var2->n_var_parts == 1);

  lc1 = var1->var_part[0].loc_chain;
  lc2 = var2->var_part[0].loc_chain;

  gcc_assert (lc1 && lc2);

  while (lc1 && lc2)
    {
      switch (loc_cmp (lc1->loc, lc2->loc))
	{
	case -1:
	  fprintf (dump_file, "removed: ");
	  print_rtl_single (dump_file, lc1->loc);
	  lc1 = lc1->next;
	  continue;
	case 0:
	  break;
	case 1:
	  fprintf (dump_file, "added: ");
	  print_rtl_single (dump_file, lc2->loc);
	  lc2 = lc2->next;
	  continue;
	default:
	  gcc_unreachable ();
	}
      lc1 = lc1->next;
      lc2 = lc2->next;
    }

  while (lc1)
    {
      fprintf (dump_file, "removed: ");
      print_rtl_single (dump_file, lc1->loc);
      lc1 = lc1->next;
    }

  while (lc2)
    {
      fprintf (dump_file, "added: ");
      print_rtl_single (dump_file, lc2->loc);
      lc2 = lc2->next;
    }
}

/* Return true if variables VAR1 and VAR2 are different.  */

static bool
variable_different_p (variable *var1, variable *var2)
{
  int i;

  if (var1 == var2)
    return false;

  if (var1->onepart != var2->onepart)
    return true;

  if (var1->n_var_parts != var2->n_var_parts)
    return true;

  if (var1->onepart && var1->n_var_parts)
    {
      gcc_checking_assert (dv_as_opaque (var1->dv) == dv_as_opaque (var2->dv)
			   && var1->n_var_parts == 1);
      /* One-part values have locations in a canonical order.  */
      return onepart_variable_different_p (var1, var2);
    }

  for (i = 0; i < var1->n_var_parts; i++)
    {
      if (VAR_PART_OFFSET (var1, i) != VAR_PART_OFFSET (var2, i))
	return true;
      if (variable_part_different_p (&var1->var_part[i], &var2->var_part[i]))
	return true;
      if (variable_part_different_p (&var2->var_part[i], &var1->var_part[i]))
	return true;
    }
  return false;
}

/* Return true if dataflow sets OLD_SET and NEW_SET differ.  */

static bool
dataflow_set_different (dataflow_set *old_set, dataflow_set *new_set)
{
  variable_iterator_type hi;
  variable *var1;
  bool diffound = false;
  bool details = (dump_file && (dump_flags & TDF_DETAILS));

#define RETRUE					\
  do						\
    {						\
      if (!details)				\
	return true;				\
      else					\
	diffound = true;			\
    }						\
  while (0)

  if (old_set->vars == new_set->vars)
    return false;

  if (shared_hash_htab (old_set->vars)->elements ()
      != shared_hash_htab (new_set->vars)->elements ())
    RETRUE;

  FOR_EACH_HASH_TABLE_ELEMENT (*shared_hash_htab (old_set->vars),
			       var1, variable, hi)
    {
      variable_table_type *htab = shared_hash_htab (new_set->vars);
      variable *var2 = htab->find_with_hash (var1->dv, dv_htab_hash (var1->dv));

      if (!var2)
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "dataflow difference found: removal of:\n");
	      dump_var (var1);
	    }
	  RETRUE;
	}
      else if (variable_different_p (var1, var2))
	{
	  if (details)
	    {
	      fprintf (dump_file, "dataflow difference found: "
		       "old and new follow:\n");
	      dump_var (var1);
	      if (dv_onepart_p (var1->dv))
		dump_onepart_variable_differences (var1, var2);
	      dump_var (var2);
	    }
	  RETRUE;
	}
    }

  /* There's no need to traverse the second hashtab unless we want to
     print the details.  If both have the same number of elements and
     the second one had all entries found in the first one, then the
     second can't have any extra entries.  */
  if (!details)
    return diffound;

  FOR_EACH_HASH_TABLE_ELEMENT (*shared_hash_htab (new_set->vars),
			       var1, variable, hi)
    {
      variable_table_type *htab = shared_hash_htab (old_set->vars);
      variable *var2 = htab->find_with_hash (var1->dv, dv_htab_hash (var1->dv));
      if (!var2)
	{
	  if (details)
	    {
	      fprintf (dump_file, "dataflow difference found: addition of:\n");
	      dump_var (var1);
	    }
	  RETRUE;
	}
    }

#undef RETRUE

  return diffound;
}

/* Free the contents of dataflow set SET.  */

static void
dataflow_set_destroy (dataflow_set *set)
{
  int i;

  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    attrs_list_clear (&set->regs[i]);

  shared_hash_destroy (set->vars);
  set->vars = NULL;
}

/* Return true if T is a tracked parameter with non-degenerate record type.  */

static bool
tracked_record_parameter_p (tree t)
{
  if (TREE_CODE (t) != PARM_DECL)
    return false;

  if (DECL_MODE (t) == BLKmode)
    return false;

  tree type = TREE_TYPE (t);
  if (TREE_CODE (type) != RECORD_TYPE)
    return false;

  if (TYPE_FIELDS (type) == NULL_TREE
      || DECL_CHAIN (TYPE_FIELDS (type)) == NULL_TREE)
    return false;

  return true;
}

/* Shall EXPR be tracked?  */

static bool
track_expr_p (tree expr, bool need_rtl)
{
  rtx decl_rtl;
  tree realdecl;

  if (TREE_CODE (expr) == DEBUG_EXPR_DECL)
    return DECL_RTL_SET_P (expr);

  /* If EXPR is not a parameter or a variable do not track it.  */
  if (!VAR_P (expr) && TREE_CODE (expr) != PARM_DECL)
    return 0;

  /* It also must have a name...  */
  if (!DECL_NAME (expr) && need_rtl)
    return 0;

  /* ... and a RTL assigned to it.  */
  decl_rtl = DECL_RTL_IF_SET (expr);
  if (!decl_rtl && need_rtl)
    return 0;

  /* If this expression is really a debug alias of some other declaration, we
     don't need to track this expression if the ultimate declaration is
     ignored.  */
  realdecl = expr;
  if (VAR_P (realdecl) && DECL_HAS_DEBUG_EXPR_P (realdecl))
    {
      realdecl = DECL_DEBUG_EXPR (realdecl);
      if (!DECL_P (realdecl))
	{
	  if (handled_component_p (realdecl)
	      || (TREE_CODE (realdecl) == MEM_REF
		  && TREE_CODE (TREE_OPERAND (realdecl, 0)) == ADDR_EXPR))
	    {
	      HOST_WIDE_INT bitsize, bitpos;
	      bool reverse;
	      tree innerdecl
		= get_ref_base_and_extent_hwi (realdecl, &bitpos,
					       &bitsize, &reverse);
	      if (!innerdecl
		  || !DECL_P (innerdecl)
		  || DECL_IGNORED_P (innerdecl)
		  /* Do not track declarations for parts of tracked record
		     parameters since we want to track them as a whole.  */
		  || tracked_record_parameter_p (innerdecl)
		  || TREE_STATIC (innerdecl)
		  || bitsize == 0
		  || bitpos + bitsize > 256)
		return 0;
	      else
		realdecl = expr;
	    }
	  else
	    return 0;
	}
    }

  /* Do not track EXPR if REALDECL it should be ignored for debugging
     purposes.  */
  if (DECL_IGNORED_P (realdecl))
    return 0;

  /* Do not track global variables until we are able to emit correct location
     list for them.  */
  if (TREE_STATIC (realdecl))
    return 0;

  /* When the EXPR is a DECL for alias of some variable (see example)
     the TREE_STATIC flag is not used.  Disable tracking all DECLs whose
     DECL_RTL contains SYMBOL_REF.

     Example:
     extern char **_dl_argv_internal __attribute__ ((alias ("_dl_argv")));
     char **_dl_argv;
  */
  if (decl_rtl && MEM_P (decl_rtl)
      && contains_symbol_ref_p (XEXP (decl_rtl, 0)))
    return 0;

  /* If RTX is a memory it should not be very large (because it would be
     an array or struct).  */
  if (decl_rtl && MEM_P (decl_rtl))
    {
      /* Do not track structures and arrays.  */
      if ((GET_MODE (decl_rtl) == BLKmode
	   || AGGREGATE_TYPE_P (TREE_TYPE (realdecl)))
	  && !tracked_record_parameter_p (realdecl))
	return 0;
      if (MEM_SIZE_KNOWN_P (decl_rtl)
	  && maybe_gt (MEM_SIZE (decl_rtl), MAX_VAR_PARTS))
	return 0;
    }

  DECL_CHANGED (expr) = 0;
  DECL_CHANGED (realdecl) = 0;
  return 1;
}

/* Determine whether a given LOC refers to the same variable part as
   EXPR+OFFSET.  */

static bool
same_variable_part_p (rtx loc, tree expr, poly_int64 offset)
{
  tree expr2;
  poly_int64 offset2;

  if (! DECL_P (expr))
    return false;

  if (REG_P (loc))
    {
      expr2 = REG_EXPR (loc);
      offset2 = REG_OFFSET (loc);
    }
  else if (MEM_P (loc))
    {
      expr2 = MEM_EXPR (loc);
      offset2 = int_mem_offset (loc);
    }
  else
    return false;

  if (! expr2 || ! DECL_P (expr2))
    return false;

  expr = var_debug_decl (expr);
  expr2 = var_debug_decl (expr2);

  return (expr == expr2 && known_eq (offset, offset2));
}

/* LOC is a REG or MEM that we would like to track if possible.
   If EXPR is null, we don't know what expression LOC refers to,
   otherwise it refers to EXPR + OFFSET.  STORE_REG_P is true if
   LOC is an lvalue register.

   Return true if EXPR is nonnull and if LOC, or some lowpart of it,
   is something we can track.  When returning true, store the mode of
   the lowpart we can track in *MODE_OUT (if nonnull) and its offset
   from EXPR in *OFFSET_OUT (if nonnull).  */

static bool
track_loc_p (rtx loc, tree expr, poly_int64 offset, bool store_reg_p,
	     machine_mode *mode_out, HOST_WIDE_INT *offset_out)
{
  machine_mode mode;

  if (expr == NULL || !track_expr_p (expr, true))
    return false;

  /* If REG was a paradoxical subreg, its REG_ATTRS will describe the
     whole subreg, but only the old inner part is really relevant.  */
  mode = GET_MODE (loc);
  if (REG_P (loc) && !HARD_REGISTER_NUM_P (ORIGINAL_REGNO (loc)))
    {
      machine_mode pseudo_mode;

      pseudo_mode = PSEUDO_REGNO_MODE (ORIGINAL_REGNO (loc));
      if (paradoxical_subreg_p (mode, pseudo_mode))
	{
	  offset += byte_lowpart_offset (pseudo_mode, mode);
	  mode = pseudo_mode;
	}
    }

  /* If LOC is a paradoxical lowpart of EXPR, refer to EXPR itself.
     Do the same if we are storing to a register and EXPR occupies
     the whole of register LOC; in that case, the whole of EXPR is
     being changed.  We exclude complex modes from the second case
     because the real and imaginary parts are represented as separate
     pseudo registers, even if the whole complex value fits into one
     hard register.  */
  if ((paradoxical_subreg_p (mode, DECL_MODE (expr))
       || (store_reg_p
	   && !COMPLEX_MODE_P (DECL_MODE (expr))
	   && hard_regno_nregs (REGNO (loc), DECL_MODE (expr)) == 1))
      && known_eq (offset + byte_lowpart_offset (DECL_MODE (expr), mode), 0))
    {
      mode = DECL_MODE (expr);
      offset = 0;
    }

  HOST_WIDE_INT const_offset;
  if (!track_offset_p (offset, &const_offset))
    return false;

  if (mode_out)
    *mode_out = mode;
  if (offset_out)
    *offset_out = const_offset;
  return true;
}

/* Return the MODE lowpart of LOC, or null if LOC is not something we
   want to track.  When returning nonnull, make sure that the attributes
   on the returned value are updated.  */

static rtx
var_lowpart (machine_mode mode, rtx loc)
{
  unsigned int regno;

  if (GET_MODE (loc) == mode)
    return loc;

  if (!REG_P (loc) && !MEM_P (loc))
    return NULL;

  poly_uint64 offset = byte_lowpart_offset (mode, GET_MODE (loc));

  if (MEM_P (loc))
    return adjust_address_nv (loc, mode, offset);

  poly_uint64 reg_offset = subreg_lowpart_offset (mode, GET_MODE (loc));
  regno = REGNO (loc) + subreg_regno_offset (REGNO (loc), GET_MODE (loc),
					     reg_offset, mode);
  return gen_rtx_REG_offset (loc, mode, regno, offset);
}

/* Carry information about uses and stores while walking rtx.  */

struct count_use_info
{
  /* The insn where the RTX is.  */
  rtx_insn *insn;

  /* The basic block where insn is.  */
  basic_block bb;

  /* The array of n_sets sets in the insn, as determined by cselib.  */
  struct cselib_set *sets;
  int n_sets;

  /* True if we're counting stores, false otherwise.  */
  bool store_p;
};

/* Find a VALUE corresponding to X.   */

static inline cselib_val *
find_use_val (rtx x, machine_mode mode, struct count_use_info *cui)
{
  int i;

  if (cui->sets)
    {
      /* This is called after uses are set up and before stores are
	 processed by cselib, so it's safe to look up srcs, but not
	 dsts.  So we look up expressions that appear in srcs or in
	 dest expressions, but we search the sets array for dests of
	 stores.  */
      if (cui->store_p)
	{
	  /* Some targets represent memset and memcpy patterns
	     by (set (mem:BLK ...) (reg:[QHSD]I ...)) or
	     (set (mem:BLK ...) (const_int ...)) or
	     (set (mem:BLK ...) (mem:BLK ...)).  Don't return anything
	     in that case, otherwise we end up with mode mismatches.  */
	  if (mode == BLKmode && MEM_P (x))
	    return NULL;
	  for (i = 0; i < cui->n_sets; i++)
	    if (cui->sets[i].dest == x)
	      return cui->sets[i].src_elt;
	}
      else
	return cselib_lookup (x, mode, 0, VOIDmode);
    }

  return NULL;
}

/* Replace all registers and addresses in an expression with VALUE
   expressions that map back to them, unless the expression is a
   register.  If no mapping is or can be performed, returns NULL.  */

static rtx
replace_expr_with_values (rtx loc)
{
  if (REG_P (loc) || GET_CODE (loc) == ENTRY_VALUE)
    return NULL;
  else if (MEM_P (loc))
    {
      cselib_val *addr = cselib_lookup (XEXP (loc, 0),
					get_address_mode (loc), 0,
					GET_MODE (loc));
      if (addr)
	return replace_equiv_address_nv (loc, addr->val_rtx);
      else
	return NULL;
    }
  else
    return cselib_subst_to_values (loc, VOIDmode);
}

/* Return true if X contains a DEBUG_EXPR.  */

static bool
rtx_debug_expr_p (const_rtx x)
{
  subrtx_iterator::array_type array;
  FOR_EACH_SUBRTX (iter, array, x, ALL)
    if (GET_CODE (*iter) == DEBUG_EXPR)
      return true;
  return false;
}

/* Determine what kind of micro operation to choose for a USE.  Return
   MO_CLOBBER if no micro operation is to be generated.  */

static enum micro_operation_type
use_type (rtx loc, struct count_use_info *cui, machine_mode *modep)
{
  tree expr;

  if (cui && cui->sets)
    {
      if (GET_CODE (loc) == VAR_LOCATION)
	{
	  if (track_expr_p (PAT_VAR_LOCATION_DECL (loc), false))
	    {
	      rtx ploc = PAT_VAR_LOCATION_LOC (loc);
	      if (! VAR_LOC_UNKNOWN_P (ploc))
		{
		  cselib_val *val = cselib_lookup (ploc, GET_MODE (loc), 1,
						   VOIDmode);

		  /* ??? flag_float_store and volatile mems are never
		     given values, but we could in theory use them for
		     locations.  */
		  gcc_assert (val || 1);
		}
	      return MO_VAL_LOC;
	    }
	  else
	    return MO_CLOBBER;
	}

      if (REG_P (loc) || MEM_P (loc))
	{
	  if (modep)
	    *modep = GET_MODE (loc);
	  if (cui->store_p)
	    {
	      if (REG_P (loc)
		  || (find_use_val (loc, GET_MODE (loc), cui)
		      && cselib_lookup (XEXP (loc, 0),
					get_address_mode (loc), 0,
					GET_MODE (loc))))
		return MO_VAL_SET;
	    }
	  else
	    {
	      cselib_val *val = find_use_val (loc, GET_MODE (loc), cui);

	      if (val && !cselib_preserved_value_p (val))
		return MO_VAL_USE;
	    }
	}
    }

  if (REG_P (loc))
    {
      gcc_assert (REGNO (loc) < FIRST_PSEUDO_REGISTER);

      if (loc == cfa_base_rtx)
	return MO_CLOBBER;
      expr = REG_EXPR (loc);

      if (!expr)
	return MO_USE_NO_VAR;
      else if (target_for_debug_bind (var_debug_decl (expr)))
	return MO_CLOBBER;
      else if (track_loc_p (loc, expr, REG_OFFSET (loc),
			    false, modep, NULL))
	return MO_USE;
      else
	return MO_USE_NO_VAR;
    }
  else if (MEM_P (loc))
    {
      expr = MEM_EXPR (loc);

      if (!expr)
	return MO_CLOBBER;
      else if (target_for_debug_bind (var_debug_decl (expr)))
	return MO_CLOBBER;
      else if (track_loc_p (loc, expr, int_mem_offset (loc),
			    false, modep, NULL)
	       /* Multi-part variables shouldn't refer to one-part
		  variable names such as VALUEs (never happens) or
		  DEBUG_EXPRs (only happens in the presence of debug
		  insns).  */
	       && (!MAY_HAVE_DEBUG_BIND_INSNS
		   || !rtx_debug_expr_p (XEXP (loc, 0))))
	return MO_USE;
      else
	return MO_CLOBBER;
    }

  return MO_CLOBBER;
}

/* Log to OUT information about micro-operation MOPT involving X in
   INSN of BB.  */

static inline void
log_op_type (rtx x, basic_block bb, rtx_insn *insn,
	     enum micro_operation_type mopt, FILE *out)
{
  fprintf (out, "bb %i op %i insn %i %s ",
	   bb->index, VTI (bb)->mos.length (),
	   INSN_UID (insn), micro_operation_type_name[mopt]);
  print_inline_rtx (out, x, 2);
  fputc ('\n', out);
}

/* Tell whether the CONCAT used to holds a VALUE and its location
   needs value resolution, i.e., an attempt of mapping the location
   back to other incoming values.  */
#define VAL_NEEDS_RESOLUTION(x) \
  (RTL_FLAG_CHECK1 ("VAL_NEEDS_RESOLUTION", (x), CONCAT)->volatil)
/* Whether the location in the CONCAT is a tracked expression, that
   should also be handled like a MO_USE.  */
#define VAL_HOLDS_TRACK_EXPR(x) \
  (RTL_FLAG_CHECK1 ("VAL_HOLDS_TRACK_EXPR", (x), CONCAT)->used)
/* Whether the location in the CONCAT should be handled like a MO_COPY
   as well.  */
#define VAL_EXPR_IS_COPIED(x) \
  (RTL_FLAG_CHECK1 ("VAL_EXPR_IS_COPIED", (x), CONCAT)->jump)
/* Whether the location in the CONCAT should be handled like a
   MO_CLOBBER as well.  */
#define VAL_EXPR_IS_CLOBBERED(x) \
  (RTL_FLAG_CHECK1 ("VAL_EXPR_IS_CLOBBERED", (x), CONCAT)->unchanging)

/* All preserved VALUEs.  */
static vec<rtx> preserved_values;

/* Ensure VAL is preserved and remember it in a vector for vt_emit_notes.  */

static void
preserve_value (cselib_val *val)
{
  cselib_preserve_value (val);
  preserved_values.safe_push (val->val_rtx);
}

/* Helper function for MO_VAL_LOC handling.  Return non-zero if
   any rtxes not suitable for CONST use not replaced by VALUEs
   are discovered.  */

static bool
non_suitable_const (const_rtx x)
{
  subrtx_iterator::array_type array;
  FOR_EACH_SUBRTX (iter, array, x, ALL)
    {
      const_rtx x = *iter;
      switch (GET_CODE (x))
	{
	case REG:
	case DEBUG_EXPR:
	case PC:
	case SCRATCH:
	case ASM_INPUT:
	case ASM_OPERANDS:
	  return true;
	case MEM:
	  if (!MEM_READONLY_P (x))
	    return true;
	  break;
	default:
	  break;
	}
    }
  return false;
}

/* Add uses (register and memory references) LOC which will be tracked
   to VTI (bb)->mos.  */

static void
add_uses (rtx loc, struct count_use_info *cui)
{
  machine_mode mode = VOIDmode;
  enum micro_operation_type type = use_type (loc, cui, &mode);

  if (type != MO_CLOBBER)
    {
      basic_block bb = cui->bb;
      micro_operation mo;

      mo.type = type;
      mo.u.loc = type == MO_USE ? var_lowpart (mode, loc) : loc;
      mo.insn = cui->insn;

      if (type == MO_VAL_LOC)
	{
	  rtx oloc = loc;
	  rtx vloc = PAT_VAR_LOCATION_LOC (oloc);
	  cselib_val *val;

	  gcc_assert (cui->sets);

	  if (MEM_P (vloc)
	      && !REG_P (XEXP (vloc, 0))
	      && !MEM_P (XEXP (vloc, 0)))
	    {
	      rtx mloc = vloc;
	      machine_mode address_mode = get_address_mode (mloc);
	      cselib_val *val
		= cselib_lookup (XEXP (mloc, 0), address_mode, 0,
				 GET_MODE (mloc));

	      if (val && !cselib_preserved_value_p (val))
		preserve_value (val);
	    }

	  if (CONSTANT_P (vloc)
	      && (GET_CODE (vloc) != CONST || non_suitable_const (vloc)))
	    /* For constants don't look up any value.  */;
	  else if (!VAR_LOC_UNKNOWN_P (vloc) && !unsuitable_loc (vloc)
		   && (val = find_use_val (vloc, GET_MODE (oloc), cui)))
	    {
	      machine_mode mode2;
	      enum micro_operation_type type2;
	      rtx nloc = NULL;
	      bool resolvable = REG_P (vloc) || MEM_P (vloc);

	      if (resolvable)
		nloc = replace_expr_with_values (vloc);

	      if (nloc)
		{
		  oloc = shallow_copy_rtx (oloc);
		  PAT_VAR_LOCATION_LOC (oloc) = nloc;
		}

	      oloc = gen_rtx_CONCAT (mode, val->val_rtx, oloc);

	      type2 = use_type (vloc, 0, &mode2);

	      gcc_assert (type2 == MO_USE || type2 == MO_USE_NO_VAR
			  || type2 == MO_CLOBBER);

	      if (type2 == MO_CLOBBER
		  && !cselib_preserved_value_p (val))
		{
		  VAL_NEEDS_RESOLUTION (oloc) = resolvable;
		  preserve_value (val);
		}
	    }
	  else if (!VAR_LOC_UNKNOWN_P (vloc))
	    {
	      oloc = shallow_copy_rtx (oloc);
	      PAT_VAR_LOCATION_LOC (oloc) = gen_rtx_UNKNOWN_VAR_LOC ();
	    }

	  mo.u.loc = oloc;
	}
      else if (type == MO_VAL_USE)
	{
	  machine_mode mode2 = VOIDmode;
	  enum micro_operation_type type2;
	  cselib_val *val = find_use_val (loc, GET_MODE (loc), cui);
	  rtx vloc, oloc = loc, nloc;

	  gcc_assert (cui->sets);

	  if (MEM_P (oloc)
	      && !REG_P (XEXP (oloc, 0))
	      && !MEM_P (XEXP (oloc, 0)))
	    {
	      rtx mloc = oloc;
	      machine_mode address_mode = get_address_mode (mloc);
	      cselib_val *val
		= cselib_lookup (XEXP (mloc, 0), address_mode, 0,
				 GET_MODE (mloc));

	      if (val && !cselib_preserved_value_p (val))
		preserve_value (val);
	    }

	  type2 = use_type (loc, 0, &mode2);

	  gcc_assert (type2 == MO_USE || type2 == MO_USE_NO_VAR
		      || type2 == MO_CLOBBER);

	  if (type2 == MO_USE)
	    vloc = var_lowpart (mode2, loc);
	  else
	    vloc = oloc;

	  /* The loc of a MO_VAL_USE may have two forms:

	     (concat val src): val is at src, a value-based
	     representation.

	     (concat (concat val use) src): same as above, with use as
	     the MO_USE tracked value, if it differs from src.

	  */

	  gcc_checking_assert (REG_P (loc) || MEM_P (loc));
	  nloc = replace_expr_with_values (loc);
	  if (!nloc)
	    nloc = oloc;

	  if (vloc != nloc)
	    oloc = gen_rtx_CONCAT (mode2, val->val_rtx, vloc);
	  else
	    oloc = val->val_rtx;

	  mo.u.loc = gen_rtx_CONCAT (mode, oloc, nloc);

	  if (type2 == MO_USE)
	    VAL_HOLDS_TRACK_EXPR (mo.u.loc) = 1;
	  if (!cselib_preserved_value_p (val))
	    {
	      VAL_NEEDS_RESOLUTION (mo.u.loc) = 1;
	      preserve_value (val);
	    }
	}
      else
	gcc_assert (type == MO_USE || type == MO_USE_NO_VAR);

      if (dump_file && (dump_flags & TDF_DETAILS))
	log_op_type (mo.u.loc, cui->bb, cui->insn, mo.type, dump_file);
      VTI (bb)->mos.safe_push (mo);
    }
}

/* Helper function for finding all uses of REG/MEM in X in insn INSN.  */

static void
add_uses_1 (rtx *x, void *cui)
{
  subrtx_var_iterator::array_type array;
  FOR_EACH_SUBRTX_VAR (iter, array, *x, NONCONST)
    add_uses (*iter, (struct count_use_info *) cui);
}

/* This is the value used during expansion of locations.  We want it
   to be unbounded, so that variables expanded deep in a recursion
   nest are fully evaluated, so that their values are cached
   correctly.  We avoid recursion cycles through other means, and we
   don't unshare RTL, so excess complexity is not a problem.  */
#define EXPR_DEPTH (INT_MAX)
/* We use this to keep too-complex expressions from being emitted as
   location notes, and then to debug information.  Users can trade
   compile time for ridiculously complex expressions, although they're
   seldom useful, and they may often have to be discarded as not
   representable anyway.  */
#define EXPR_USE_DEPTH (param_max_vartrack_expr_depth)

/* Attempt to reverse the EXPR operation in the debug info and record
   it in the cselib table.  Say for reg1 = reg2 + 6 even when reg2 is
   no longer live we can express its value as VAL - 6.  */

static void
reverse_op (rtx val, const_rtx expr, rtx_insn *insn)
{
  rtx src, arg, ret;
  cselib_val *v;
  struct elt_loc_list *l;
  enum rtx_code code;
  int count;

  if (GET_CODE (expr) != SET)
    return;

  if (!REG_P (SET_DEST (expr)) || GET_MODE (val) != GET_MODE (SET_DEST (expr)))
    return;

  src = SET_SRC (expr);
  switch (GET_CODE (src))
    {
    case PLUS:
    case MINUS:
    case XOR:
    case NOT:
    case NEG:
      if (!REG_P (XEXP (src, 0)))
	return;
      break;
    case SIGN_EXTEND:
    case ZERO_EXTEND:
      if (!REG_P (XEXP (src, 0)) && !MEM_P (XEXP (src, 0)))
	return;
      break;
    default:
      return;
    }

  if (!SCALAR_INT_MODE_P (GET_MODE (src)) || XEXP (src, 0) == cfa_base_rtx)
    return;

  v = cselib_lookup (XEXP (src, 0), GET_MODE (XEXP (src, 0)), 0, VOIDmode);
  if (!v || !cselib_preserved_value_p (v))
    return;

  /* Use canonical V to avoid creating multiple redundant expressions
     for different VALUES equivalent to V.  */
  v = canonical_cselib_val (v);

  /* Adding a reverse op isn't useful if V already has an always valid
     location.  Ignore ENTRY_VALUE, while it is always constant, we should
     prefer non-ENTRY_VALUE locations whenever possible.  */
  for (l = v->locs, count = 0; l; l = l->next, count++)
    if (CONSTANT_P (l->loc)
	&& (GET_CODE (l->loc) != CONST || !references_value_p (l->loc, 0)))
      return;
    /* Avoid creating too large locs lists.  */
    else if (count == param_max_vartrack_reverse_op_size)
      return;

  switch (GET_CODE (src))
    {
    case NOT:
    case NEG:
      if (GET_MODE (v->val_rtx) != GET_MODE (val))
	return;
      ret = gen_rtx_fmt_e (GET_CODE (src), GET_MODE (val), val);
      break;
    case SIGN_EXTEND:
    case ZERO_EXTEND:
      ret = gen_lowpart_SUBREG (GET_MODE (v->val_rtx), val);
      break;
    case XOR:
      code = XOR;
      goto binary;
    case PLUS:
      code = MINUS;
      goto binary;
    case MINUS:
      code = PLUS;
      goto binary;
    binary:
      if (GET_MODE (v->val_rtx) != GET_MODE (val))
	return;
      arg = XEXP (src, 1);
      if (!CONST_INT_P (arg) && GET_CODE (arg) != SYMBOL_REF)
	{
	  arg = cselib_expand_value_rtx (arg, scratch_regs, 5);
	  if (arg == NULL_RTX)
	    return;
	  if (!CONST_INT_P (arg) && GET_CODE (arg) != SYMBOL_REF)
	    return;
	}
      ret = simplify_gen_binary (code, GET_MODE (val), val, arg);
      break;
    default:
      gcc_unreachable ();
    }

  cselib_add_permanent_equiv (v, ret, insn);
}

/* Add stores (register and memory references) LOC which will be tracked
   to VTI (bb)->mos.  EXPR is the RTL expression containing the store.
   CUIP->insn is instruction which the LOC is part of.  */

static void
add_stores (rtx loc, const_rtx expr, void *cuip)
{
  machine_mode mode = VOIDmode, mode2;
  struct count_use_info *cui = (struct count_use_info *)cuip;
  basic_block bb = cui->bb;
  micro_operation mo;
  rtx oloc = loc, nloc, src = NULL;
  enum micro_operation_type type = use_type (loc, cui, &mode);
  bool track_p = false;
  cselib_val *v;
  bool resolve, preserve;

  if (type == MO_CLOBBER)
    return;

  mode2 = mode;

  if (REG_P (loc))
    {
      gcc_assert (loc != cfa_base_rtx);
      if ((GET_CODE (expr) == CLOBBER && type != MO_VAL_SET)
	  || !(track_p = use_type (loc, NULL, &mode2) == MO_USE)
	  || GET_CODE (expr) == CLOBBER)
	{
	  mo.type = MO_CLOBBER;
	  mo.u.loc = loc;
	  if (GET_CODE (expr) == SET
	      && (SET_DEST (expr) == loc
		  || (GET_CODE (SET_DEST (expr)) == STRICT_LOW_PART
		      && XEXP (SET_DEST (expr), 0) == loc))
	      && !unsuitable_loc (SET_SRC (expr))
	      && find_use_val (loc, mode, cui))
	    {
	      gcc_checking_assert (type == MO_VAL_SET);
	      mo.u.loc = gen_rtx_SET (loc, SET_SRC (expr));
	    }
	}
      else
	{
	  if (GET_CODE (expr) == SET
	      && SET_DEST (expr) == loc
	      && GET_CODE (SET_SRC (expr)) != ASM_OPERANDS)
	    src = var_lowpart (mode2, SET_SRC (expr));
	  loc = var_lowpart (mode2, loc);

	  if (src == NULL)
	    {
	      mo.type = MO_SET;
	      mo.u.loc = loc;
	    }
	  else
	    {
	      rtx xexpr = gen_rtx_SET (loc, src);
	      if (same_variable_part_p (src, REG_EXPR (loc), REG_OFFSET (loc)))
		{
		  /* If this is an instruction copying (part of) a parameter
		     passed by invisible reference to its register location,
		     pretend it's a SET so that the initial memory location
		     is discarded, as the parameter register can be reused
		     for other purposes and we do not track locations based
		     on generic registers.  */
		  if (MEM_P (src)
		      && REG_EXPR (loc)
		      && TREE_CODE (REG_EXPR (loc)) == PARM_DECL
		      && DECL_MODE (REG_EXPR (loc)) != BLKmode
		      && MEM_P (DECL_INCOMING_RTL (REG_EXPR (loc)))
		      && XEXP (DECL_INCOMING_RTL (REG_EXPR (loc)), 0)
			 != arg_pointer_rtx)
		    mo.type = MO_SET;
		  else
		    mo.type = MO_COPY;
		}
	      else
		mo.type = MO_SET;
	      mo.u.loc = xexpr;
	    }
	}
      mo.insn = cui->insn;
    }
  else if (MEM_P (loc)
	   && ((track_p = use_type (loc, NULL, &mode2) == MO_USE)
	       || cui->sets))
    {
      if (MEM_P (loc) && type == MO_VAL_SET
	  && !REG_P (XEXP (loc, 0))
	  && !MEM_P (XEXP (loc, 0)))
	{
	  rtx mloc = loc;
	  machine_mode address_mode = get_address_mode (mloc);
	  cselib_val *val = cselib_lookup (XEXP (mloc, 0),
					   address_mode, 0,
					   GET_MODE (mloc));

	  if (val && !cselib_preserved_value_p (val))
	    preserve_value (val);
	}

      if (GET_CODE (expr) == CLOBBER || !track_p)
	{
	  mo.type = MO_CLOBBER;
	  mo.u.loc = track_p ? var_lowpart (mode2, loc) : loc;
	}
      else
	{
	  if (GET_CODE (expr) == SET
	      && SET_DEST (expr) == loc
	      && GET_CODE (SET_SRC (expr)) != ASM_OPERANDS)
	    src = var_lowpart (mode2, SET_SRC (expr));
	  loc = var_lowpart (mode2, loc);

	  if (src == NULL)
	    {
	      mo.type = MO_SET;
	      mo.u.loc = loc;
	    }
	  else
	    {
	      rtx xexpr = gen_rtx_SET (loc, src);
	      if (same_variable_part_p (SET_SRC (xexpr),
					MEM_EXPR (loc),
					int_mem_offset (loc)))
		mo.type = MO_COPY;
	      else
		mo.type = MO_SET;
	      mo.u.loc = xexpr;
	    }
	}
      mo.insn = cui->insn;
    }
  else
    return;

  if (type != MO_VAL_SET)
    goto log_and_return;

  v = find_use_val (oloc, mode, cui);

  if (!v)
    goto log_and_return;

  resolve = preserve = !cselib_preserved_value_p (v);

  /* We cannot track values for multiple-part variables, so we track only
     locations for tracked record parameters.  */
  if (track_p
      && REG_P (loc)
      && REG_EXPR (loc)
      && tracked_record_parameter_p (REG_EXPR (loc)))
    {
      /* Although we don't use the value here, it could be used later by the
	 mere virtue of its existence as the operand of the reverse operation
	 that gave rise to it (typically extension/truncation).  Make sure it
	 is preserved as required by vt_expand_var_loc_chain.  */
      if (preserve)
	preserve_value (v);
      goto log_and_return;
    }

  if (loc == stack_pointer_rtx
      && (maybe_ne (hard_frame_pointer_adjustment, -1)
	  || (!frame_pointer_needed && !ACCUMULATE_OUTGOING_ARGS))
      && preserve)
    cselib_set_value_sp_based (v);

  /* Don't record MO_VAL_SET for VALUEs that can be described using
     cfa_base_rtx or cfa_base_rtx + CONST_INT, cselib already knows
     all the needed equivalences and they shouldn't change depending
     on which register holds that VALUE in some instruction.  */
  if (!frame_pointer_needed
      && cfa_base_rtx
      && cselib_sp_derived_value_p (v)
      && loc == stack_pointer_rtx)
    {
      if (preserve)
	preserve_value (v);
      return;
    }

  nloc = replace_expr_with_values (oloc);
  if (nloc)
    oloc = nloc;

  if (GET_CODE (PATTERN (cui->insn)) == COND_EXEC)
    {
      cselib_val *oval = cselib_lookup (oloc, GET_MODE (oloc), 0, VOIDmode);

      if (oval == v)
	return;
      gcc_assert (REG_P (oloc) || MEM_P (oloc));

      if (oval && !cselib_preserved_value_p (oval))
	{
	  micro_operation moa;

	  preserve_value (oval);

	  moa.type = MO_VAL_USE;
	  moa.u.loc = gen_rtx_CONCAT (mode, oval->val_rtx, oloc);
	  VAL_NEEDS_RESOLUTION (moa.u.loc) = 1;
	  moa.insn = cui->insn;

	  if (dump_file && (dump_flags & TDF_DETAILS))
	    log_op_type (moa.u.loc, cui->bb, cui->insn,
			 moa.type, dump_file);
	  VTI (bb)->mos.safe_push (moa);
	}

      resolve = false;
    }
  else if (resolve && GET_CODE (mo.u.loc) == SET)
    {
      if (REG_P (SET_SRC (expr)) || MEM_P (SET_SRC (expr)))
	nloc = replace_expr_with_values (SET_SRC (expr));
      else
	nloc = NULL_RTX;

      /* Avoid the mode mismatch between oexpr and expr.  */
      if (!nloc && mode != mode2)
	{
	  nloc = SET_SRC (expr);
	  gcc_assert (oloc == SET_DEST (expr));
	}

      if (nloc && nloc != SET_SRC (mo.u.loc))
	oloc = gen_rtx_SET (oloc, nloc);
      else
	{
	  if (oloc == SET_DEST (mo.u.loc))
	    /* No point in duplicating.  */
	    oloc = mo.u.loc;
	  if (!REG_P (SET_SRC (mo.u.loc)))
	    resolve = false;
	}
    }
  else if (!resolve)
    {
      if (GET_CODE (mo.u.loc) == SET
	  && oloc == SET_DEST (mo.u.loc))
	/* No point in duplicating.  */
	oloc = mo.u.loc;
    }
  else
    resolve = false;

  loc = gen_rtx_CONCAT (mode, v->val_rtx, oloc);

  if (mo.u.loc != oloc)
    loc = gen_rtx_CONCAT (GET_MODE (mo.u.loc), loc, mo.u.loc);

  /* The loc of a MO_VAL_SET may have various forms:

     (concat val dst): dst now holds val

     (concat val (set dst src)): dst now holds val, copied from src

     (concat (concat val dstv) dst): dst now holds val; dstv is dst
     after replacing mems and non-top-level regs with values.

     (concat (concat val dstv) (set dst src)): dst now holds val,
     copied from src.  dstv is a value-based representation of dst, if
     it differs from dst.  If resolution is needed, src is a REG, and
     its mode is the same as that of val.

     (concat (concat val (set dstv srcv)) (set dst src)): src
     copied to dst, holding val.  dstv and srcv are value-based
     representations of dst and src, respectively.

  */

  if (GET_CODE (PATTERN (cui->insn)) != COND_EXEC)
    reverse_op (v->val_rtx, expr, cui->insn);

  mo.u.loc = loc;

  if (track_p)
    VAL_HOLDS_TRACK_EXPR (loc) = 1;
  if (preserve)
    {
      VAL_NEEDS_RESOLUTION (loc) = resolve;
      preserve_value (v);
    }
  if (mo.type == MO_CLOBBER)
    VAL_EXPR_IS_CLOBBERED (loc) = 1;
  if (mo.type == MO_COPY)
    VAL_EXPR_IS_COPIED (loc) = 1;

  mo.type = MO_VAL_SET;

 log_and_return:
  if (dump_file && (dump_flags & TDF_DETAILS))
    log_op_type (mo.u.loc, cui->bb, cui->insn, mo.type, dump_file);
  VTI (bb)->mos.safe_push (mo);
}

/* Arguments to the call.  */
static rtx call_arguments;

/* Compute call_arguments.  */

static void
prepare_call_arguments (basic_block bb, rtx_insn *insn)
{
  rtx link, x, call;
  rtx prev, cur, next;
  rtx this_arg = NULL_RTX;
  tree type = NULL_TREE, t, fndecl = NULL_TREE;
  tree obj_type_ref = NULL_TREE;
  CUMULATIVE_ARGS args_so_far_v;
  cumulative_args_t args_so_far;

  memset (&args_so_far_v, 0, sizeof (args_so_far_v));
  args_so_far = pack_cumulative_args (&args_so_far_v);
  call = get_call_rtx_from (insn);
  if (call)
    {
      if (GET_CODE (XEXP (XEXP (call, 0), 0)) == SYMBOL_REF)
	{
	  rtx symbol = XEXP (XEXP (call, 0), 0);
	  if (SYMBOL_REF_DECL (symbol))
	    fndecl = SYMBOL_REF_DECL (symbol);
	}
      if (fndecl == NULL_TREE)
	fndecl = MEM_EXPR (XEXP (call, 0));
      if (fndecl
	  && TREE_CODE (TREE_TYPE (fndecl)) != FUNCTION_TYPE
	  && TREE_CODE (TREE_TYPE (fndecl)) != METHOD_TYPE)
	fndecl = NULL_TREE;
      if (fndecl && TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
	type = TREE_TYPE (fndecl);
      if (fndecl && TREE_CODE (fndecl) != FUNCTION_DECL)
	{
	  if (TREE_CODE (fndecl) == INDIRECT_REF
	      && TREE_CODE (TREE_OPERAND (fndecl, 0)) == OBJ_TYPE_REF)
	    obj_type_ref = TREE_OPERAND (fndecl, 0);
	  fndecl = NULL_TREE;
	}
      if (type)
	{
	  for (t = TYPE_ARG_TYPES (type); t && t != void_list_node;
	       t = TREE_CHAIN (t))
	    if (TREE_CODE (TREE_VALUE (t)) == REFERENCE_TYPE
		&& INTEGRAL_TYPE_P (TREE_TYPE (TREE_VALUE (t))))
	      break;
	  if ((t == NULL || t == void_list_node) && obj_type_ref == NULL_TREE)
	    type = NULL;
	  else
	    {
	      int nargs ATTRIBUTE_UNUSED = list_length (TYPE_ARG_TYPES (type));
	      link = CALL_INSN_FUNCTION_USAGE (insn);
#ifndef PCC_STATIC_STRUCT_RETURN
	      if (aggregate_value_p (TREE_TYPE (type), type)
		  && targetm.calls.struct_value_rtx (type, 0) == 0)
		{
		  tree struct_addr = build_pointer_type (TREE_TYPE (type));
		  function_arg_info arg (struct_addr, /*named=*/true);
		  rtx reg;
		  INIT_CUMULATIVE_ARGS (args_so_far_v, type, NULL_RTX, fndecl,
					nargs + 1);
		  reg = targetm.calls.function_arg (args_so_far, arg);
		  targetm.calls.function_arg_advance (args_so_far, arg);
		  if (reg == NULL_RTX)
		    {
		      for (; link; link = XEXP (link, 1))
			if (GET_CODE (XEXP (link, 0)) == USE
			    && MEM_P (XEXP (XEXP (link, 0), 0)))
			  {
			    link = XEXP (link, 1);
			    break;
			  }
		    }
		}
	      else
#endif
		INIT_CUMULATIVE_ARGS (args_so_far_v, type, NULL_RTX, fndecl,
				      nargs);
	      if (obj_type_ref && TYPE_ARG_TYPES (type) != void_list_node)
		{
		  t = TYPE_ARG_TYPES (type);
		  function_arg_info arg (TREE_VALUE (t), /*named=*/true);
		  this_arg = targetm.calls.function_arg (args_so_far, arg);
		  if (this_arg && !REG_P (this_arg))
		    this_arg = NULL_RTX;
		  else if (this_arg == NULL_RTX)
		    {
		      for (; link; link = XEXP (link, 1))
			if (GET_CODE (XEXP (link, 0)) == USE
			    && MEM_P (XEXP (XEXP (link, 0), 0)))
			  {
			    this_arg = XEXP (XEXP (link, 0), 0);
			    break;
			  }
		    }
		}
	    }
	}
    }
  t = type ? TYPE_ARG_TYPES (type) : NULL_TREE;

  for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
    if (GET_CODE (XEXP (link, 0)) == USE)
      {
	rtx item = NULL_RTX;
	x = XEXP (XEXP (link, 0), 0);
	if (GET_MODE (link) == VOIDmode
	    || GET_MODE (link) == BLKmode
	    || (GET_MODE (link) != GET_MODE (x)
		&& ((GET_MODE_CLASS (GET_MODE (link)) != MODE_INT
		     && GET_MODE_CLASS (GET_MODE (link)) != MODE_PARTIAL_INT)
		    || (GET_MODE_CLASS (GET_MODE (x)) != MODE_INT
			&& GET_MODE_CLASS (GET_MODE (x)) != MODE_PARTIAL_INT))))
	  /* Can't do anything for these, if the original type mode
	     isn't known or can't be converted.  */;
	else if (REG_P (x))
	  {
	    cselib_val *val = cselib_lookup (x, GET_MODE (x), 0, VOIDmode);
	    scalar_int_mode mode;
	    if (val && cselib_preserved_value_p (val))
	      item = val->val_rtx;
	    else if (is_a <scalar_int_mode> (GET_MODE (x), &mode))
	      {
		opt_scalar_int_mode mode_iter;
		FOR_EACH_WIDER_MODE (mode_iter, mode)
		  {
		    mode = mode_iter.require ();
		    if (GET_MODE_BITSIZE (mode) > BITS_PER_WORD)
		      break;

		    rtx reg = simplify_subreg (mode, x, GET_MODE (x), 0);
		    if (reg == NULL_RTX || !REG_P (reg))
		      continue;
		    val = cselib_lookup (reg, mode, 0, VOIDmode);
		    if (val && cselib_preserved_value_p (val))
		      {
			item = val->val_rtx;
			break;
		      }
		  }
	      }
	  }
	else if (MEM_P (x))
	  {
	    rtx mem = x;
	    cselib_val *val;

	    if (!frame_pointer_needed)
	      {
		class adjust_mem_data amd;
		amd.mem_mode = VOIDmode;
		amd.stack_adjust = -VTI (bb)->out.stack_adjust;
		amd.store = true;
		mem = simplify_replace_fn_rtx (mem, NULL_RTX, adjust_mems,
					       &amd);
		gcc_assert (amd.side_effects.is_empty ());
	      }
	    val = cselib_lookup (mem, GET_MODE (mem), 0, VOIDmode);
	    if (val && cselib_preserved_value_p (val))
	      item = val->val_rtx;
	    else if (GET_MODE_CLASS (GET_MODE (mem)) != MODE_INT
		     && GET_MODE_CLASS (GET_MODE (mem)) != MODE_PARTIAL_INT)
	      {
		/* For non-integer stack argument see also if they weren't
		   initialized by integers.  */
		scalar_int_mode imode;
		if (int_mode_for_mode (GET_MODE (mem)).exists (&imode)
		    && imode != GET_MODE (mem))
		  {
		    val = cselib_lookup (adjust_address_nv (mem, imode, 0),
					 imode, 0, VOIDmode);
		    if (val && cselib_preserved_value_p (val))
		      item = lowpart_subreg (GET_MODE (x), val->val_rtx,
					     imode);
		  }
	      }
	  }
	if (item)
	  {
	    rtx x2 = x;
	    if (GET_MODE (item) != GET_MODE (link))
	      item = lowpart_subreg (GET_MODE (link), item, GET_MODE (item));
	    if (GET_MODE (x2) != GET_MODE (link))
	      x2 = lowpart_subreg (GET_MODE (link), x2, GET_MODE (x2));
	    item = gen_rtx_CONCAT (GET_MODE (link), x2, item);
	    call_arguments
	      = gen_rtx_EXPR_LIST (VOIDmode, item, call_arguments);
	  }
	if (t && t != void_list_node)
	  {
	    rtx reg;
	    function_arg_info arg (TREE_VALUE (t), /*named=*/true);
	    apply_pass_by_reference_rules (&args_so_far_v, arg);
	    reg = targetm.calls.function_arg (args_so_far, arg);
	    if (TREE_CODE (arg.type) == REFERENCE_TYPE
		&& INTEGRAL_TYPE_P (TREE_TYPE (arg.type))
		&& reg
		&& REG_P (reg)
		&& GET_MODE (reg) == arg.mode
		&& (GET_MODE_CLASS (arg.mode) == MODE_INT
		    || GET_MODE_CLASS (arg.mode) == MODE_PARTIAL_INT)
		&& REG_P (x)
		&& REGNO (x) == REGNO (reg)
		&& GET_MODE (x) == arg.mode
		&& item)
	      {
		machine_mode indmode
		  = TYPE_MODE (TREE_TYPE (arg.type));
		rtx mem = gen_rtx_MEM (indmode, x);
		cselib_val *val = cselib_lookup (mem, indmode, 0, VOIDmode);
		if (val && cselib_preserved_value_p (val))
		  {
		    item = gen_rtx_CONCAT (indmode, mem, val->val_rtx);
		    call_arguments = gen_rtx_EXPR_LIST (VOIDmode, item,
							call_arguments);
		  }
		else
		  {
		    struct elt_loc_list *l;
		    tree initial;

		    /* Try harder, when passing address of a constant
		       pool integer it can be easily read back.  */
		    item = XEXP (item, 1);
		    if (GET_CODE (item) == SUBREG)
		      item = SUBREG_REG (item);
		    gcc_assert (GET_CODE (item) == VALUE);
		    val = CSELIB_VAL_PTR (item);
		    for (l = val->locs; l; l = l->next)
		      if (GET_CODE (l->loc) == SYMBOL_REF
			  && TREE_CONSTANT_POOL_ADDRESS_P (l->loc)
			  && SYMBOL_REF_DECL (l->loc)
			  && DECL_INITIAL (SYMBOL_REF_DECL (l->loc)))
			{
			  initial = DECL_INITIAL (SYMBOL_REF_DECL (l->loc));
			  if (tree_fits_shwi_p (initial))
			    {
			      item = GEN_INT (tree_to_shwi (initial));
			      item = gen_rtx_CONCAT (indmode, mem, item);
			      call_arguments
				= gen_rtx_EXPR_LIST (VOIDmode, item,
						     call_arguments);
			    }
			  break;
			}
		  }
	      }
	    targetm.calls.function_arg_advance (args_so_far, arg);
	    t = TREE_CHAIN (t);
	  }
      }

  /* Add debug arguments.  */
  if (fndecl
      && TREE_CODE (fndecl) == FUNCTION_DECL
      && DECL_HAS_DEBUG_ARGS_P (fndecl))
    {
      vec<tree, va_gc> **debug_args = decl_debug_args_lookup (fndecl);
      if (debug_args)
	{
	  unsigned int ix;
	  tree param;
	  for (ix = 0; vec_safe_iterate (*debug_args, ix, &param); ix += 2)
	    {
	      rtx item;
	      tree dtemp = (**debug_args)[ix + 1];
	      machine_mode mode = DECL_MODE (dtemp);
	      item = gen_rtx_DEBUG_PARAMETER_REF (mode, param);
	      item = gen_rtx_CONCAT (mode, item, DECL_RTL_KNOWN_SET (dtemp));
	      call_arguments = gen_rtx_EXPR_LIST (VOIDmode, item,
						  call_arguments);
	    }
	}
    }

  /* Reverse call_arguments chain.  */
  prev = NULL_RTX;
  for (cur = call_arguments; cur; cur = next)
    {
      next = XEXP (cur, 1);
      XEXP (cur, 1) = prev;
      prev = cur;
    }
  call_arguments = prev;

  x = get_call_rtx_from (insn);
  if (x)
    {
      x = XEXP (XEXP (x, 0), 0);
      if (GET_CODE (x) == SYMBOL_REF)
	/* Don't record anything.  */;
      else if (CONSTANT_P (x))
	{
	  x = gen_rtx_CONCAT (GET_MODE (x) == VOIDmode ? Pmode : GET_MODE (x),
			      pc_rtx, x);
	  call_arguments
	    = gen_rtx_EXPR_LIST (VOIDmode, x, call_arguments);
	}
      else
	{
	  cselib_val *val = cselib_lookup (x, GET_MODE (x), 0, VOIDmode);
	  if (val && cselib_preserved_value_p (val))
	    {
	      x = gen_rtx_CONCAT (GET_MODE (x), pc_rtx, val->val_rtx);
	      call_arguments
		= gen_rtx_EXPR_LIST (VOIDmode, x, call_arguments);
	    }
	}
    }
  if (this_arg)
    {
      machine_mode mode
	= TYPE_MODE (TREE_TYPE (OBJ_TYPE_REF_EXPR (obj_type_ref)));
      rtx clobbered = gen_rtx_MEM (mode, this_arg);
      HOST_WIDE_INT token
	= tree_to_shwi (OBJ_TYPE_REF_TOKEN (obj_type_ref));
      if (token)
	clobbered = plus_constant (mode, clobbered,
				   token * GET_MODE_SIZE (mode));
      clobbered = gen_rtx_MEM (mode, clobbered);
      x = gen_rtx_CONCAT (mode, gen_rtx_CLOBBER (VOIDmode, pc_rtx), clobbered);
      call_arguments
	= gen_rtx_EXPR_LIST (VOIDmode, x, call_arguments);
    }
}

/* Callback for cselib_record_sets_hook, that records as micro
   operations uses and stores in an insn after cselib_record_sets has
   analyzed the sets in an insn, but before it modifies the stored
   values in the internal tables, unless cselib_record_sets doesn't
   call it directly (perhaps because we're not doing cselib in the
   first place, in which case sets and n_sets will be 0).  */

static void
add_with_sets (rtx_insn *insn, struct cselib_set *sets, int n_sets)
{
  basic_block bb = BLOCK_FOR_INSN (insn);
  int n1, n2;
  struct count_use_info cui;
  micro_operation *mos;

  cselib_hook_called = true;

  cui.insn = insn;
  cui.bb = bb;
  cui.sets = sets;
  cui.n_sets = n_sets;

  n1 = VTI (bb)->mos.length ();
  cui.store_p = false;
  note_uses (&PATTERN (insn), add_uses_1, &cui);
  n2 = VTI (bb)->mos.length () - 1;
  mos = VTI (bb)->mos.address ();

  /* Order the MO_USEs to be before MO_USE_NO_VARs and MO_VAL_USE, and
     MO_VAL_LOC last.  */
  while (n1 < n2)
    {
      while (n1 < n2 && mos[n1].type == MO_USE)
	n1++;
      while (n1 < n2 && mos[n2].type != MO_USE)
	n2--;
      if (n1 < n2)
	std::swap (mos[n1], mos[n2]);
    }

  n2 = VTI (bb)->mos.length () - 1;
  while (n1 < n2)
    {
      while (n1 < n2 && mos[n1].type != MO_VAL_LOC)
	n1++;
      while (n1 < n2 && mos[n2].type == MO_VAL_LOC)
	n2--;
      if (n1 < n2)
	std::swap (mos[n1], mos[n2]);
    }

  if (CALL_P (insn))
    {
      micro_operation mo;

      mo.type = MO_CALL;
      mo.insn = insn;
      mo.u.loc = call_arguments;
      call_arguments = NULL_RTX;

      if (dump_file && (dump_flags & TDF_DETAILS))
	log_op_type (PATTERN (insn), bb, insn, mo.type, dump_file);
      VTI (bb)->mos.safe_push (mo);
    }

  n1 = VTI (bb)->mos.length ();
  /* This will record NEXT_INSN (insn), such that we can
     insert notes before it without worrying about any
     notes that MO_USEs might emit after the insn.  */
  cui.store_p = true;
  note_stores (insn, add_stores, &cui);
  n2 = VTI (bb)->mos.length () - 1;
  mos = VTI (bb)->mos.address ();

  /* Order the MO_VAL_USEs first (note_stores does nothing
     on DEBUG_INSNs, so there are no MO_VAL_LOCs from this
     insn), then MO_CLOBBERs, then MO_SET/MO_COPY/MO_VAL_SET.  */
  while (n1 < n2)
    {
      while (n1 < n2 && mos[n1].type == MO_VAL_USE)
	n1++;
      while (n1 < n2 && mos[n2].type != MO_VAL_USE)
	n2--;
      if (n1 < n2)
	std::swap (mos[n1], mos[n2]);
    }

  n2 = VTI (bb)->mos.length () - 1;
  while (n1 < n2)
    {
      while (n1 < n2 && mos[n1].type == MO_CLOBBER)
	n1++;
      while (n1 < n2 && mos[n2].type != MO_CLOBBER)
	n2--;
      if (n1 < n2)
	std::swap (mos[n1], mos[n2]);
    }
}

static enum var_init_status
find_src_status (dataflow_set *in, rtx src)
{
  tree decl = NULL_TREE;
  enum var_init_status status = VAR_INIT_STATUS_UNINITIALIZED;

  if (! flag_var_tracking_uninit)
    status = VAR_INIT_STATUS_INITIALIZED;

  if (src && REG_P (src))
    decl = var_debug_decl (REG_EXPR (src));
  else if (src && MEM_P (src))
    decl = var_debug_decl (MEM_EXPR (src));

  if (src && decl)
    status = get_init_value (in, src, dv_from_decl (decl));

  return status;
}

/* SRC is the source of an assignment.  Use SET to try to find what
   was ultimately assigned to SRC.  Return that value if known,
   otherwise return SRC itself.  */

static rtx
find_src_set_src (dataflow_set *set, rtx src)
{
  tree decl = NULL_TREE;   /* The variable being copied around.          */
  rtx set_src = NULL_RTX;  /* The value for "decl" stored in "src".      */
  variable *var;
  location_chain *nextp;
  int i;
  bool found;

  if (src && REG_P (src))
    decl = var_debug_decl (REG_EXPR (src));
  else if (src && MEM_P (src))
    decl = var_debug_decl (MEM_EXPR (src));

  if (src && decl)
    {
      decl_or_value dv = dv_from_decl (decl);

      var = shared_hash_find (set->vars, dv);
      if (var)
	{
	  found = false;
	  for (i = 0; i < var->n_var_parts && !found; i++)
	    for (nextp = var->var_part[i].loc_chain; nextp && !found;
		 nextp = nextp->next)
	      if (rtx_equal_p (nextp->loc, src))
		{
		  set_src = nextp->set_src;
		  found = true;
		}

	}
    }

  return set_src;
}

/* Compute the changes of variable locations in the basic block BB.  */

static bool
compute_bb_dataflow (basic_block bb)
{
  unsigned int i;
  micro_operation *mo;
  bool changed;
  dataflow_set old_out;
  dataflow_set *in = &VTI (bb)->in;
  dataflow_set *out = &VTI (bb)->out;

  dataflow_set_init (&old_out);
  dataflow_set_copy (&old_out, out);
  dataflow_set_copy (out, in);

  if (MAY_HAVE_DEBUG_BIND_INSNS)
    local_get_addr_cache = new hash_map<rtx, rtx>;

  FOR_EACH_VEC_ELT (VTI (bb)->mos, i, mo)
    {
      rtx_insn *insn = mo->insn;

      switch (mo->type)
	{
	  case MO_CALL:
	    dataflow_set_clear_at_call (out, insn);
	    break;

	  case MO_USE:
	    {
	      rtx loc = mo->u.loc;

	      if (REG_P (loc))
		var_reg_set (out, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
	      else if (MEM_P (loc))
		var_mem_set (out, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
	    }
	    break;

	  case MO_VAL_LOC:
	    {
	      rtx loc = mo->u.loc;
	      rtx val, vloc;
	      tree var;

	      if (GET_CODE (loc) == CONCAT)
		{
		  val = XEXP (loc, 0);
		  vloc = XEXP (loc, 1);
		}
	      else
		{
		  val = NULL_RTX;
		  vloc = loc;
		}

	      var = PAT_VAR_LOCATION_DECL (vloc);

	      clobber_variable_part (out, NULL_RTX,
				     dv_from_decl (var), 0, NULL_RTX);
	      if (val)
		{
		  if (VAL_NEEDS_RESOLUTION (loc))
		    val_resolve (out, val, PAT_VAR_LOCATION_LOC (vloc), insn);
		  set_variable_part (out, val, dv_from_decl (var), 0,
				     VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
				     INSERT);
		}
	      else if (!VAR_LOC_UNKNOWN_P (PAT_VAR_LOCATION_LOC (vloc)))
		set_variable_part (out, PAT_VAR_LOCATION_LOC (vloc),
				   dv_from_decl (var), 0,
				   VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
				   INSERT);
	    }
	    break;

	  case MO_VAL_USE:
	    {
	      rtx loc = mo->u.loc;
	      rtx val, vloc, uloc;

	      vloc = uloc = XEXP (loc, 1);
	      val = XEXP (loc, 0);

	      if (GET_CODE (val) == CONCAT)
		{
		  uloc = XEXP (val, 1);
		  val = XEXP (val, 0);
		}

	      if (VAL_NEEDS_RESOLUTION (loc))
		val_resolve (out, val, vloc, insn);
	      else
		val_store (out, val, uloc, insn, false);

	      if (VAL_HOLDS_TRACK_EXPR (loc))
		{
		  if (GET_CODE (uloc) == REG)
		    var_reg_set (out, uloc, VAR_INIT_STATUS_UNINITIALIZED,
				 NULL);
		  else if (GET_CODE (uloc) == MEM)
		    var_mem_set (out, uloc, VAR_INIT_STATUS_UNINITIALIZED,
				 NULL);
		}
	    }
	    break;

	  case MO_VAL_SET:
	    {
	      rtx loc = mo->u.loc;
	      rtx val, vloc, uloc;
	      rtx dstv, srcv;

	      vloc = loc;
	      uloc = XEXP (vloc, 1);
	      val = XEXP (vloc, 0);
	      vloc = uloc;

	      if (GET_CODE (uloc) == SET)
		{
		  dstv = SET_DEST (uloc);
		  srcv = SET_SRC (uloc);
		}
	      else
		{
		  dstv = uloc;
		  srcv = NULL;
		}

	      if (GET_CODE (val) == CONCAT)
		{
		  dstv = vloc = XEXP (val, 1);
		  val = XEXP (val, 0);
		}

	      if (GET_CODE (vloc) == SET)
		{
		  srcv = SET_SRC (vloc);

		  gcc_assert (val != srcv);
		  gcc_assert (vloc == uloc || VAL_NEEDS_RESOLUTION (loc));

		  dstv = vloc = SET_DEST (vloc);

		  if (VAL_NEEDS_RESOLUTION (loc))
		    val_resolve (out, val, srcv, insn);
		}
	      else if (VAL_NEEDS_RESOLUTION (loc))
		{
		  gcc_assert (GET_CODE (uloc) == SET
			      && GET_CODE (SET_SRC (uloc)) == REG);
		  val_resolve (out, val, SET_SRC (uloc), insn);
		}

	      if (VAL_HOLDS_TRACK_EXPR (loc))
		{
		  if (VAL_EXPR_IS_CLOBBERED (loc))
		    {
		      if (REG_P (uloc))
			var_reg_delete (out, uloc, true);
		      else if (MEM_P (uloc))
			{
			  gcc_assert (MEM_P (dstv));
			  gcc_assert (MEM_ATTRS (dstv) == MEM_ATTRS (uloc));
			  var_mem_delete (out, dstv, true);
			}
		    }
		  else
		    {
		      bool copied_p = VAL_EXPR_IS_COPIED (loc);
		      rtx src = NULL, dst = uloc;
		      enum var_init_status status = VAR_INIT_STATUS_INITIALIZED;

		      if (GET_CODE (uloc) == SET)
			{
			  src = SET_SRC (uloc);
			  dst = SET_DEST (uloc);
			}

		      if (copied_p)
			{
			  if (flag_var_tracking_uninit)
			    {
			      status = find_src_status (in, src);

			      if (status == VAR_INIT_STATUS_UNKNOWN)
				status = find_src_status (out, src);
			    }

			  src = find_src_set_src (in, src);
			}

		      if (REG_P (dst))
			var_reg_delete_and_set (out, dst, !copied_p,
						status, srcv);
		      else if (MEM_P (dst))
			{
			  gcc_assert (MEM_P (dstv));
			  gcc_assert (MEM_ATTRS (dstv) == MEM_ATTRS (dst));
			  var_mem_delete_and_set (out, dstv, !copied_p,
						  status, srcv);
			}
		    }
		}
	      else if (REG_P (uloc))
		var_regno_delete (out, REGNO (uloc));
	      else if (MEM_P (uloc))
		{
		  gcc_checking_assert (GET_CODE (vloc) == MEM);
		  gcc_checking_assert (dstv == vloc);
		  if (dstv != vloc)
		    clobber_overlapping_mems (out, vloc);
		}

	      val_store (out, val, dstv, insn, true);
	    }
	    break;

	  case MO_SET:
	    {
	      rtx loc = mo->u.loc;
	      rtx set_src = NULL;

	      if (GET_CODE (loc) == SET)
		{
		  set_src = SET_SRC (loc);
		  loc = SET_DEST (loc);
		}

	      if (REG_P (loc))
		var_reg_delete_and_set (out, loc, true, VAR_INIT_STATUS_INITIALIZED,
					set_src);
	      else if (MEM_P (loc))
		var_mem_delete_and_set (out, loc, true, VAR_INIT_STATUS_INITIALIZED,
					set_src);
	    }
	    break;

	  case MO_COPY:
	    {
	      rtx loc = mo->u.loc;
	      enum var_init_status src_status;
	      rtx set_src = NULL;

	      if (GET_CODE (loc) == SET)
		{
		  set_src = SET_SRC (loc);
		  loc = SET_DEST (loc);
		}

	      if (! flag_var_tracking_uninit)
		src_status = VAR_INIT_STATUS_INITIALIZED;
	      else
		{
		  src_status = find_src_status (in, set_src);

		  if (src_status == VAR_INIT_STATUS_UNKNOWN)
		    src_status = find_src_status (out, set_src);
		}

	      set_src = find_src_set_src (in, set_src);

	      if (REG_P (loc))
		var_reg_delete_and_set (out, loc, false, src_status, set_src);
	      else if (MEM_P (loc))
		var_mem_delete_and_set (out, loc, false, src_status, set_src);
	    }
	    break;

	  case MO_USE_NO_VAR:
	    {
	      rtx loc = mo->u.loc;

	      if (REG_P (loc))
		var_reg_delete (out, loc, false);
	      else if (MEM_P (loc))
		var_mem_delete (out, loc, false);
	    }
	    break;

	  case MO_CLOBBER:
	    {
	      rtx loc = mo->u.loc;

	      if (REG_P (loc))
		var_reg_delete (out, loc, true);
	      else if (MEM_P (loc))
		var_mem_delete (out, loc, true);
	    }
	    break;

	  case MO_ADJUST:
	    out->stack_adjust += mo->u.adjust;
	    break;
	}
    }

  if (MAY_HAVE_DEBUG_BIND_INSNS)
    {
      delete local_get_addr_cache;
      local_get_addr_cache = NULL;

      dataflow_set_equiv_regs (out);
      shared_hash_htab (out->vars)
	->traverse <dataflow_set *, canonicalize_values_mark> (out);
      shared_hash_htab (out->vars)
	->traverse <dataflow_set *, canonicalize_values_star> (out);
      if (flag_checking)
	shared_hash_htab (out->vars)
	  ->traverse <dataflow_set *, canonicalize_loc_order_check> (out);
    }
  changed = dataflow_set_different (&old_out, out);
  dataflow_set_destroy (&old_out);
  return changed;
}

/* Find the locations of variables in the whole function.  */

static bool
vt_find_locations (void)
{
  bb_heap_t *worklist = new bb_heap_t (LONG_MIN);
  bb_heap_t *pending = new bb_heap_t (LONG_MIN);
  sbitmap in_worklist, in_pending;
  basic_block bb;
  edge e;
  int *bb_order;
  int *rc_order;
  int i;
  int htabsz = 0;
  int htabmax = param_max_vartrack_size;
  bool success = true;
  unsigned int n_blocks_processed = 0;

  timevar_push (TV_VAR_TRACKING_DATAFLOW);
  /* Compute reverse completion order of depth first search of the CFG
     so that the data-flow runs faster.  */
  rc_order = XNEWVEC (int, n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS);
  bb_order = XNEWVEC (int, last_basic_block_for_fn (cfun));
  auto_bitmap exit_bbs;
  bitmap_set_bit (exit_bbs, EXIT_BLOCK);
  auto_vec<std::pair<int, int> > toplevel_scc_extents;
  int n = rev_post_order_and_mark_dfs_back_seme
    (cfun, single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), exit_bbs, true,
     rc_order, &toplevel_scc_extents);
  for (i = 0; i < n; i++)
    bb_order[rc_order[i]] = i;

  in_worklist = sbitmap_alloc (last_basic_block_for_fn (cfun));
  in_pending = sbitmap_alloc (last_basic_block_for_fn (cfun));
  bitmap_clear (in_worklist);
  bitmap_clear (in_pending);

  /* We're performing the dataflow iteration independently over the
     toplevel SCCs plus leading non-cyclic entry blocks and separately
     over the tail.  That ensures best memory locality and the least
     number of visited blocks.  */
  unsigned extent = 0;
  int curr_start = -1;
  int curr_end = -1;
  do
    {
      curr_start = curr_end + 1;
      if (toplevel_scc_extents.length () <= extent)
	curr_end = n - 1;
      else
	curr_end = toplevel_scc_extents[extent++].second;

      for (int i = curr_start; i <= curr_end; ++i)
	{
	  pending->insert (i, BASIC_BLOCK_FOR_FN (cfun, rc_order[i]));
	  bitmap_set_bit (in_pending, rc_order[i]);
	}

      while (success && !pending->empty ())
	{
	  std::swap (worklist, pending);
	  std::swap (in_worklist, in_pending);

	  while (!worklist->empty ())
	    {
	      bool changed;
	      edge_iterator ei;
	      int oldinsz, oldoutsz;

	      bb = worklist->extract_min ();
	      bitmap_clear_bit (in_worklist, bb->index);

	      if (VTI (bb)->in.vars)
		{
		  htabsz -= (shared_hash_htab (VTI (bb)->in.vars)->size ()
			     + shared_hash_htab (VTI (bb)->out.vars)->size ());
		  oldinsz = shared_hash_htab (VTI (bb)->in.vars)->elements ();
		  oldoutsz = shared_hash_htab (VTI (bb)->out.vars)->elements ();
		}
	      else
		oldinsz = oldoutsz = 0;

	      if (MAY_HAVE_DEBUG_BIND_INSNS)
		{
		  dataflow_set *in = &VTI (bb)->in, *first_out = NULL;
		  bool first = true, adjust = false;

		  /* Calculate the IN set as the intersection of
		     predecessor OUT sets.  */

		  dataflow_set_clear (in);
		  dst_can_be_shared = true;

		  FOR_EACH_EDGE (e, ei, bb->preds)
		    if (!VTI (e->src)->flooded)
		      gcc_assert (bb_order[bb->index]
				  <= bb_order[e->src->index]);
		    else if (first)
		      {
			dataflow_set_copy (in, &VTI (e->src)->out);
			first_out = &VTI (e->src)->out;
			first = false;
		      }
		    else
		      {
			dataflow_set_merge (in, &VTI (e->src)->out);
			adjust = true;
		      }

		  if (adjust)
		    {
		      dataflow_post_merge_adjust (in, &VTI (bb)->permp);

		      if (flag_checking)
			/* Merge and merge_adjust should keep entries in
			   canonical order.  */
			shared_hash_htab (in->vars)
			  ->traverse <dataflow_set *,
				      canonicalize_loc_order_check> (in);

		      if (dst_can_be_shared)
			{
			  shared_hash_destroy (in->vars);
			  in->vars = shared_hash_copy (first_out->vars);
			}
		    }

		  VTI (bb)->flooded = true;
		}
	      else
		{
		  /* Calculate the IN set as union of predecessor OUT sets.  */
		  dataflow_set_clear (&VTI (bb)->in);
		  FOR_EACH_EDGE (e, ei, bb->preds)
		    dataflow_set_union (&VTI (bb)->in, &VTI (e->src)->out);
		}

	      changed = compute_bb_dataflow (bb);
	      n_blocks_processed++;
	      htabsz += (shared_hash_htab (VTI (bb)->in.vars)->size ()
			 + shared_hash_htab (VTI (bb)->out.vars)->size ());

	      if (htabmax && htabsz > htabmax)
		{
		  if (MAY_HAVE_DEBUG_BIND_INSNS)
		    inform (DECL_SOURCE_LOCATION (cfun->decl),
			    "variable tracking size limit exceeded with "
			    "%<-fvar-tracking-assignments%>, retrying without");
		  else
		    inform (DECL_SOURCE_LOCATION (cfun->decl),
			    "variable tracking size limit exceeded");
		  success = false;
		  break;
		}

	      if (changed)
		{
		  FOR_EACH_EDGE (e, ei, bb->succs)
		    {
		      if (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
			continue;

		      /* Iterate to an earlier block in RPO in the next
			 round, iterate to the same block immediately.  */
		      if (bb_order[e->dest->index] < bb_order[bb->index])
			{
			  gcc_assert (bb_order[e->dest->index] >= curr_start);
			  if (!bitmap_bit_p (in_pending, e->dest->index))
			    {
			      /* Send E->DEST to next round.  */
			      bitmap_set_bit (in_pending, e->dest->index);
			      pending->insert (bb_order[e->dest->index],
					       e->dest);
			    }
			}
		      else if (bb_order[e->dest->index] <= curr_end
			       && !bitmap_bit_p (in_worklist, e->dest->index))
			{
			  /* Add E->DEST to current round or delay
			     processing if it is in the next SCC.  */
			  bitmap_set_bit (in_worklist, e->dest->index);
			  worklist->insert (bb_order[e->dest->index],
					    e->dest);
			}
		    }
		}

	      if (dump_file)
		fprintf (dump_file,
			 "BB %i: in %i (was %i), out %i (was %i), rem %i + %i, "
			 "tsz %i\n", bb->index,
			 (int)shared_hash_htab (VTI (bb)->in.vars)->size (),
			 oldinsz,
			 (int)shared_hash_htab (VTI (bb)->out.vars)->size (),
			 oldoutsz,
			 (int)worklist->nodes (), (int)pending->nodes (),
			 htabsz);

	      if (dump_file && (dump_flags & TDF_DETAILS))
		{
		  fprintf (dump_file, "BB %i IN:\n", bb->index);
		  dump_dataflow_set (&VTI (bb)->in);
		  fprintf (dump_file, "BB %i OUT:\n", bb->index);
		  dump_dataflow_set (&VTI (bb)->out);
		}
	    }
	}
    }
  while (curr_end != n - 1);

  statistics_counter_event (cfun, "compute_bb_dataflow times",
			    n_blocks_processed);

  if (success && MAY_HAVE_DEBUG_BIND_INSNS)
    FOR_EACH_BB_FN (bb, cfun)
      gcc_assert (VTI (bb)->flooded);

  free (rc_order);
  free (bb_order);
  delete worklist;
  delete pending;
  sbitmap_free (in_worklist);
  sbitmap_free (in_pending);

  timevar_pop (TV_VAR_TRACKING_DATAFLOW);
  return success;
}

/* Print the content of the LIST to dump file.  */

static void
dump_attrs_list (attrs *list)
{
  for (; list; list = list->next)
    {
      if (dv_is_decl_p (list->dv))
	print_mem_expr (dump_file, dv_as_decl (list->dv));
      else
	print_rtl_single (dump_file, dv_as_value (list->dv));
      fprintf (dump_file, "+" HOST_WIDE_INT_PRINT_DEC, list->offset);
    }
  fprintf (dump_file, "\n");
}

/* Print the information about variable *SLOT to dump file.  */

int
dump_var_tracking_slot (variable **slot, void *data ATTRIBUTE_UNUSED)
{
  variable *var = *slot;

  dump_var (var);

  /* Continue traversing the hash table.  */
  return 1;
}

/* Print the information about variable VAR to dump file.  */

static void
dump_var (variable *var)
{
  int i;
  location_chain *node;

  if (dv_is_decl_p (var->dv))
    {
      const_tree decl = dv_as_decl (var->dv);

      if (DECL_NAME (decl))
	{
	  fprintf (dump_file, "  name: %s",
		   IDENTIFIER_POINTER (DECL_NAME (decl)));
	  if (dump_flags & TDF_UID)
	    fprintf (dump_file, "D.%u", DECL_UID (decl));
	}
      else if (TREE_CODE (decl) == DEBUG_EXPR_DECL)
	fprintf (dump_file, "  name: D#%u", DEBUG_TEMP_UID (decl));
      else
	fprintf (dump_file, "  name: D.%u", DECL_UID (decl));
      fprintf (dump_file, "\n");
    }
  else
    {
      fputc (' ', dump_file);
      print_rtl_single (dump_file, dv_as_value (var->dv));
    }

  for (i = 0; i < var->n_var_parts; i++)
    {
      fprintf (dump_file, "    offset %ld\n",
	       (long)(var->onepart ? 0 : VAR_PART_OFFSET (var, i)));
      for (node = var->var_part[i].loc_chain; node; node = node->next)
	{
	  fprintf (dump_file, "      ");
	  if (node->init == VAR_INIT_STATUS_UNINITIALIZED)
	    fprintf (dump_file, "[uninit]");
	  print_rtl_single (dump_file, node->loc);
	}
    }
}

/* Print the information about variables from hash table VARS to dump file.  */

static void
dump_vars (variable_table_type *vars)
{
  if (!vars->is_empty ())
    {
      fprintf (dump_file, "Variables:\n");
      vars->traverse <void *, dump_var_tracking_slot> (NULL);
    }
}

/* Print the dataflow set SET to dump file.  */

static void
dump_dataflow_set (dataflow_set *set)
{
  int i;

  fprintf (dump_file, "Stack adjustment: " HOST_WIDE_INT_PRINT_DEC "\n",
	   set->stack_adjust);
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    {
      if (set->regs[i])
	{
	  fprintf (dump_file, "Reg %d:", i);
	  dump_attrs_list (set->regs[i]);
	}
    }
  dump_vars (shared_hash_htab (set->vars));
  fprintf (dump_file, "\n");
}

/* Print the IN and OUT sets for each basic block to dump file.  */

static void
dump_dataflow_sets (void)
{
  basic_block bb;

  FOR_EACH_BB_FN (bb, cfun)
    {
      fprintf (dump_file, "\nBasic block %d:\n", bb->index);
      fprintf (dump_file, "IN:\n");
      dump_dataflow_set (&VTI (bb)->in);
      fprintf (dump_file, "OUT:\n");
      dump_dataflow_set (&VTI (bb)->out);
    }
}

/* Return the variable for DV in dropped_values, inserting one if
   requested with INSERT.  */

static inline variable *
variable_from_dropped (decl_or_value dv, enum insert_option insert)
{
  variable **slot;
  variable *empty_var;
  onepart_enum onepart;

  slot = dropped_values->find_slot_with_hash (dv, dv_htab_hash (dv), insert);

  if (!slot)
    return NULL;

  if (*slot)
    return *slot;

  gcc_checking_assert (insert == INSERT);

  onepart = dv_onepart_p (dv);

  gcc_checking_assert (onepart == ONEPART_VALUE || onepart == ONEPART_DEXPR);

  empty_var = onepart_pool_allocate (onepart);
  empty_var->dv = dv;
  empty_var->refcount = 1;
  empty_var->n_var_parts = 0;
  empty_var->onepart = onepart;
  empty_var->in_changed_variables = false;
  empty_var->var_part[0].loc_chain = NULL;
  empty_var->var_part[0].cur_loc = NULL;
  VAR_LOC_1PAUX (empty_var) = NULL;
  set_dv_changed (dv, true);

  *slot = empty_var;

  return empty_var;
}

/* Recover the one-part aux from dropped_values.  */

static struct onepart_aux *
recover_dropped_1paux (variable *var)
{
  variable *dvar;

  gcc_checking_assert (var->onepart);

  if (VAR_LOC_1PAUX (var))
    return VAR_LOC_1PAUX (var);

  if (var->onepart == ONEPART_VDECL)
    return NULL;

  dvar = variable_from_dropped (var->dv, NO_INSERT);

  if (!dvar)
    return NULL;

  VAR_LOC_1PAUX (var) = VAR_LOC_1PAUX (dvar);
  VAR_LOC_1PAUX (dvar) = NULL;

  return VAR_LOC_1PAUX (var);
}

/* Add variable VAR to the hash table of changed variables and
   if it has no locations delete it from SET's hash table.  */

static void
variable_was_changed (variable *var, dataflow_set *set)
{
  hashval_t hash = dv_htab_hash (var->dv);

  if (emit_notes)
    {
      variable **slot;

      /* Remember this decl or VALUE has been added to changed_variables.  */
      set_dv_changed (var->dv, true);

      slot = changed_variables->find_slot_with_hash (var->dv, hash, INSERT);

      if (*slot)
	{
	  variable *old_var = *slot;
	  gcc_assert (old_var->in_changed_variables);
	  old_var->in_changed_variables = false;
	  if (var != old_var && var->onepart)
	    {
	      /* Restore the auxiliary info from an empty variable
		 previously created for changed_variables, so it is
		 not lost.  */
	      gcc_checking_assert (!VAR_LOC_1PAUX (var));
	      VAR_LOC_1PAUX (var) = VAR_LOC_1PAUX (old_var);
	      VAR_LOC_1PAUX (old_var) = NULL;
	    }
	  variable_htab_free (*slot);
	}

      if (set && var->n_var_parts == 0)
	{
	  onepart_enum onepart = var->onepart;
	  variable *empty_var = NULL;
	  variable **dslot = NULL;

	  if (onepart == ONEPART_VALUE || onepart == ONEPART_DEXPR)
	    {
	      dslot = dropped_values->find_slot_with_hash (var->dv,
							   dv_htab_hash (var->dv),
							   INSERT);
	      empty_var = *dslot;

	      if (empty_var)
		{
		  gcc_checking_assert (!empty_var->in_changed_variables);
		  if (!VAR_LOC_1PAUX (var))
		    {
		      VAR_LOC_1PAUX (var) = VAR_LOC_1PAUX (empty_var);
		      VAR_LOC_1PAUX (empty_var) = NULL;
		    }
		  else
		    gcc_checking_assert (!VAR_LOC_1PAUX (empty_var));
		}
	    }

	  if (!empty_var)
	    {
	      empty_var = onepart_pool_allocate (onepart);
	      empty_var->dv = var->dv;
	      empty_var->refcount = 1;
	      empty_var->n_var_parts = 0;
	      empty_var->onepart = onepart;
	      if (dslot)
		{
		  empty_var->refcount++;
		  *dslot = empty_var;
		}
	    }
	  else
	    empty_var->refcount++;
	  empty_var->in_changed_variables = true;
	  *slot = empty_var;
	  if (onepart)
	    {
	      empty_var->var_part[0].loc_chain = NULL;
	      empty_var->var_part[0].cur_loc = NULL;
	      VAR_LOC_1PAUX (empty_var) = VAR_LOC_1PAUX (var);
	      VAR_LOC_1PAUX (var) = NULL;
	    }
	  goto drop_var;
	}
      else
	{
	  if (var->onepart && !VAR_LOC_1PAUX (var))
	    recover_dropped_1paux (var);
	  var->refcount++;
	  var->in_changed_variables = true;
	  *slot = var;
	}
    }
  else
    {
      gcc_assert (set);
      if (var->n_var_parts == 0)
	{
	  variable **slot;

	drop_var:
	  slot = shared_hash_find_slot_noinsert (set->vars, var->dv);
	  if (slot)
	    {
	      if (shared_hash_shared (set->vars))
		slot = shared_hash_find_slot_unshare (&set->vars, var->dv,
						      NO_INSERT);
	      shared_hash_htab (set->vars)->clear_slot (slot);
	    }
	}
    }
}

/* Look for the index in VAR->var_part corresponding to OFFSET.
   Return -1 if not found.  If INSERTION_POINT is non-NULL, the
   referenced int will be set to the index that the part has or should
   have, if it should be inserted.  */

static inline int
find_variable_location_part (variable *var, HOST_WIDE_INT offset,
			     int *insertion_point)
{
  int pos, low, high;

  if (var->onepart)
    {
      if (offset != 0)
	return -1;

      if (insertion_point)
	*insertion_point = 0;

      return var->n_var_parts - 1;
    }

  /* Find the location part.  */
  low = 0;
  high = var->n_var_parts;
  while (low != high)
    {
      pos = (low + high) / 2;
      if (VAR_PART_OFFSET (var, pos) < offset)
	low = pos + 1;
      else
	high = pos;
    }
  pos = low;

  if (insertion_point)
    *insertion_point = pos;

  if (pos < var->n_var_parts && VAR_PART_OFFSET (var, pos) == offset)
    return pos;

  return -1;
}

static variable **
set_slot_part (dataflow_set *set, rtx loc, variable **slot,
	       decl_or_value dv, HOST_WIDE_INT offset,
	       enum var_init_status initialized, rtx set_src)
{
  int pos;
  location_chain *node, *next;
  location_chain **nextp;
  variable *var;
  onepart_enum onepart;

  var = *slot;

  if (var)
    onepart = var->onepart;
  else
    onepart = dv_onepart_p (dv);

  gcc_checking_assert (offset == 0 || !onepart);
  gcc_checking_assert (loc != dv_as_opaque (dv));

  if (! flag_var_tracking_uninit)
    initialized = VAR_INIT_STATUS_INITIALIZED;

  if (!var)
    {
      /* Create new variable information.  */
      var = onepart_pool_allocate (onepart);
      var->dv = dv;
      var->refcount = 1;
      var->n_var_parts = 1;
      var->onepart = onepart;
      var->in_changed_variables = false;
      if (var->onepart)
	VAR_LOC_1PAUX (var) = NULL;
      else
	VAR_PART_OFFSET (var, 0) = offset;
      var->var_part[0].loc_chain = NULL;
      var->var_part[0].cur_loc = NULL;
      *slot = var;
      pos = 0;
      nextp = &var->var_part[0].loc_chain;
    }
  else if (onepart)
    {
      int r = -1, c = 0;

      gcc_assert (dv_as_opaque (var->dv) == dv_as_opaque (dv));

      pos = 0;

      if (GET_CODE (loc) == VALUE)
	{
	  for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
	       nextp = &node->next)
	    if (GET_CODE (node->loc) == VALUE)
	      {
		if (node->loc == loc)
		  {
		    r = 0;
		    break;
		  }
		if (canon_value_cmp (node->loc, loc))
		  c++;
		else
		  {
		    r = 1;
		    break;
		  }
	      }
	    else if (REG_P (node->loc) || MEM_P (node->loc))
	      c++;
	    else
	      {
		r = 1;
		break;
	      }
	}
      else if (REG_P (loc))
	{
	  for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
	       nextp = &node->next)
	    if (REG_P (node->loc))
	      {
		if (REGNO (node->loc) < REGNO (loc))
		  c++;
		else
		  {
		    if (REGNO (node->loc) == REGNO (loc))
		      r = 0;
		    else
		      r = 1;
		    break;
		  }
	      }
	    else
	      {
		r = 1;
		break;
	      }
	}
      else if (MEM_P (loc))
	{
	  for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
	       nextp = &node->next)
	    if (REG_P (node->loc))
	      c++;
	    else if (MEM_P (node->loc))
	      {
		if ((r = loc_cmp (XEXP (node->loc, 0), XEXP (loc, 0))) >= 0)
		  break;
		else
		  c++;
	      }
	    else
	      {
		r = 1;
		break;
	      }
	}
      else
	for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
	     nextp = &node->next)
	  if ((r = loc_cmp (node->loc, loc)) >= 0)
	    break;
	  else
	    c++;

      if (r == 0)
	return slot;

      if (shared_var_p (var, set->vars))
	{
	  slot = unshare_variable (set, slot, var, initialized);
	  var = *slot;
	  for (nextp = &var->var_part[0].loc_chain; c;
	       nextp = &(*nextp)->next)
	    c--;
	  gcc_assert ((!node && !*nextp) || node->loc == (*nextp)->loc);
	}
    }
  else
    {
      int inspos = 0;

      gcc_assert (dv_as_decl (var->dv) == dv_as_decl (dv));

      pos = find_variable_location_part (var, offset, &inspos);

      if (pos >= 0)
	{
	  node = var->var_part[pos].loc_chain;

	  if (node
	      && ((REG_P (node->loc) && REG_P (loc)
		   && REGNO (node->loc) == REGNO (loc))
		  || rtx_equal_p (node->loc, loc)))
	    {
	      /* LOC is in the beginning of the chain so we have nothing
		 to do.  */
	      if (node->init < initialized)
		node->init = initialized;
	      if (set_src != NULL)
		node->set_src = set_src;

	      return slot;
	    }
	  else
	    {
	      /* We have to make a copy of a shared variable.  */
	      if (shared_var_p (var, set->vars))
		{
		  slot = unshare_variable (set, slot, var, initialized);
		  var = *slot;
		}
	    }
	}
      else
	{
	  /* We have not found the location part, new one will be created.  */

	  /* We have to make a copy of the shared variable.  */
	  if (shared_var_p (var, set->vars))
	    {
	      slot = unshare_variable (set, slot, var, initialized);
	      var = *slot;
	    }

	  /* We track only variables whose size is <= MAX_VAR_PARTS bytes
	     thus there are at most MAX_VAR_PARTS different offsets.  */
	  gcc_assert (var->n_var_parts < MAX_VAR_PARTS
		      && (!var->n_var_parts || !onepart));

	  /* We have to move the elements of array starting at index
	     inspos to the next position.  */
	  for (pos = var->n_var_parts; pos > inspos; pos--)
	    var->var_part[pos] = var->var_part[pos - 1];

	  var->n_var_parts++;
	  gcc_checking_assert (!onepart);
	  VAR_PART_OFFSET (var, pos) = offset;
	  var->var_part[pos].loc_chain = NULL;
	  var->var_part[pos].cur_loc = NULL;
	}

      /* Delete the location from the list.  */
      nextp = &var->var_part[pos].loc_chain;
      for (node = var->var_part[pos].loc_chain; node; node = next)
	{
	  next = node->next;
	  if ((REG_P (node->loc) && REG_P (loc)
	       && REGNO (node->loc) == REGNO (loc))
	      || rtx_equal_p (node->loc, loc))
	    {
	      /* Save these values, to assign to the new node, before
		 deleting this one.  */
	      if (node->init > initialized)
		initialized = node->init;
	      if (node->set_src != NULL && set_src == NULL)
		set_src = node->set_src;
	      if (var->var_part[pos].cur_loc == node->loc)
		var->var_part[pos].cur_loc = NULL;
	      delete node;
	      *nextp = next;
	      break;
	    }
	  else
	    nextp = &node->next;
	}

      nextp = &var->var_part[pos].loc_chain;
    }

  /* Add the location to the beginning.  */
  node = new location_chain;
  node->loc = loc;
  node->init = initialized;
  node->set_src = set_src;
  node->next = *nextp;
  *nextp = node;

  /* If no location was emitted do so.  */
  if (var->var_part[pos].cur_loc == NULL)
    variable_was_changed (var, set);

  return slot;
}

/* Set the part of variable's location in the dataflow set SET.  The
   variable part is specified by variable's declaration in DV and
   offset OFFSET and the part's location by LOC.  IOPT should be
   NO_INSERT if the variable is known to be in SET already and the
   variable hash table must not be resized, and INSERT otherwise.  */

static void
set_variable_part (dataflow_set *set, rtx loc,
		   decl_or_value dv, HOST_WIDE_INT offset,
		   enum var_init_status initialized, rtx set_src,
		   enum insert_option iopt)
{
  variable **slot;

  if (iopt == NO_INSERT)
    slot = shared_hash_find_slot_noinsert (set->vars, dv);
  else
    {
      slot = shared_hash_find_slot (set->vars, dv);
      if (!slot)
	slot = shared_hash_find_slot_unshare (&set->vars, dv, iopt);
    }
  set_slot_part (set, loc, slot, dv, offset, initialized, set_src);
}

/* Remove all recorded register locations for the given variable part
   from dataflow set SET, except for those that are identical to loc.
   The variable part is specified by variable's declaration or value
   DV and offset OFFSET.  */

static variable **
clobber_slot_part (dataflow_set *set, rtx loc, variable **slot,
		   HOST_WIDE_INT offset, rtx set_src)
{
  variable *var = *slot;
  int pos = find_variable_location_part (var, offset, NULL);

  if (pos >= 0)
    {
      location_chain *node, *next;

      /* Remove the register locations from the dataflow set.  */
      next = var->var_part[pos].loc_chain;
      for (node = next; node; node = next)
	{
	  next = node->next;
	  if (node->loc != loc
	      && (!flag_var_tracking_uninit
		  || !set_src
		  || MEM_P (set_src)
		  || !rtx_equal_p (set_src, node->set_src)))
	    {
	      if (REG_P (node->loc))
		{
		  attrs *anode, *anext;
		  attrs **anextp;

		  /* Remove the variable part from the register's
		     list, but preserve any other variable parts
		     that might be regarded as live in that same
		     register.  */
		  anextp = &set->regs[REGNO (node->loc)];
		  for (anode = *anextp; anode; anode = anext)
		    {
		      anext = anode->next;
		      if (dv_as_opaque (anode->dv) == dv_as_opaque (var->dv)
			  && anode->offset == offset)
			{
			  delete anode;
			  *anextp = anext;
			}
		      else
			anextp = &anode->next;
		    }
		}

	      slot = delete_slot_part (set, node->loc, slot, offset);
	    }
	}
    }

  return slot;
}

/* Remove all recorded register locations for the given variable part
   from dataflow set SET, except for those that are identical to loc.
   The variable part is specified by variable's declaration or value
   DV and offset OFFSET.  */

static void
clobber_variable_part (dataflow_set *set, rtx loc, decl_or_value dv,
		       HOST_WIDE_INT offset, rtx set_src)
{
  variable **slot;

  if (!dv_as_opaque (dv)
      || (!dv_is_value_p (dv) && ! DECL_P (dv_as_decl (dv))))
    return;

  slot = shared_hash_find_slot_noinsert (set->vars, dv);
  if (!slot)
    return;

  clobber_slot_part (set, loc, slot, offset, set_src);
}

/* Delete the part of variable's location from dataflow set SET.  The
   variable part is specified by its SET->vars slot SLOT and offset
   OFFSET and the part's location by LOC.  */

static variable **
delete_slot_part (dataflow_set *set, rtx loc, variable **slot,
		  HOST_WIDE_INT offset)
{
  variable *var = *slot;
  int pos = find_variable_location_part (var, offset, NULL);

  if (pos >= 0)
    {
      location_chain *node, *next;
      location_chain **nextp;
      bool changed;
      rtx cur_loc;

      if (shared_var_p (var, set->vars))
	{
	  /* If the variable contains the location part we have to
	     make a copy of the variable.  */
	  for (node = var->var_part[pos].loc_chain; node;
	       node = node->next)
	    {
	      if ((REG_P (node->loc) && REG_P (loc)
		   && REGNO (node->loc) == REGNO (loc))
		  || rtx_equal_p (node->loc, loc))
		{
		  slot = unshare_variable (set, slot, var,
					   VAR_INIT_STATUS_UNKNOWN);
		  var = *slot;
		  break;
		}
	    }
	}

      if (pos == 0 && var->onepart && VAR_LOC_1PAUX (var))
	cur_loc = VAR_LOC_FROM (var);
      else
	cur_loc = var->var_part[pos].cur_loc;

      /* Delete the location part.  */
      changed = false;
      nextp = &var->var_part[pos].loc_chain;
      for (node = *nextp; node; node = next)
	{
	  next = node->next;
	  if ((REG_P (node->loc) && REG_P (loc)
	       && REGNO (node->loc) == REGNO (loc))
	      || rtx_equal_p (node->loc, loc))
	    {
	      /* If we have deleted the location which was last emitted
		 we have to emit new location so add the variable to set
		 of changed variables.  */
	      if (cur_loc == node->loc)
		{
		  changed = true;
		  var->var_part[pos].cur_loc = NULL;
		  if (pos == 0 && var->onepart && VAR_LOC_1PAUX (var))
		    VAR_LOC_FROM (var) = NULL;
		}
	      delete node;
	      *nextp = next;
	      break;
	    }
	  else
	    nextp = &node->next;
	}

      if (var->var_part[pos].loc_chain == NULL)
	{
	  changed = true;
	  var->n_var_parts--;
	  while (pos < var->n_var_parts)
	    {
	      var->var_part[pos] = var->var_part[pos + 1];
	      pos++;
	    }
	}
      if (changed)
	variable_was_changed (var, set);
    }

  return slot;
}

/* Delete the part of variable's location from dataflow set SET.  The
   variable part is specified by variable's declaration or value DV
   and offset OFFSET and the part's location by LOC.  */

static void
delete_variable_part (dataflow_set *set, rtx loc, decl_or_value dv,
		      HOST_WIDE_INT offset)
{
  variable **slot = shared_hash_find_slot_noinsert (set->vars, dv);
  if (!slot)
    return;

  delete_slot_part (set, loc, slot, offset);
}


/* Structure for passing some other parameters to function
   vt_expand_loc_callback.  */
class expand_loc_callback_data
{
public:
  /* The variables and values active at this point.  */
  variable_table_type *vars;

  /* Stack of values and debug_exprs under expansion, and their
     children.  */
  auto_vec<rtx, 4> expanding;

  /* Stack of values and debug_exprs whose expansion hit recursion
     cycles.  They will have VALUE_RECURSED_INTO marked when added to
     this list.  This flag will be cleared if any of its dependencies
     resolves to a valid location.  So, if the flag remains set at the
     end of the search, we know no valid location for this one can
     possibly exist.  */
  auto_vec<rtx, 4> pending;

  /* The maximum depth among the sub-expressions under expansion.
     Zero indicates no expansion so far.  */
  expand_depth depth;
};

/* Allocate the one-part auxiliary data structure for VAR, with enough
   room for COUNT dependencies.  */

static void
loc_exp_dep_alloc (variable *var, int count)
{
  size_t allocsize;

  gcc_checking_assert (var->onepart);

  /* We can be called with COUNT == 0 to allocate the data structure
     without any dependencies, e.g. for the backlinks only.  However,
     if we are specifying a COUNT, then the dependency list must have
     been emptied before.  It would be possible to adjust pointers or
     force it empty here, but this is better done at an earlier point
     in the algorithm, so we instead leave an assertion to catch
     errors.  */
  gcc_checking_assert (!count
		       || VAR_LOC_DEP_VEC (var) == NULL
		       || VAR_LOC_DEP_VEC (var)->is_empty ());

  if (VAR_LOC_1PAUX (var) && VAR_LOC_DEP_VEC (var)->space (count))
    return;

  allocsize = offsetof (struct onepart_aux, deps)
	      + deps_vec::embedded_size (count);

  if (VAR_LOC_1PAUX (var))
    {
      VAR_LOC_1PAUX (var) = XRESIZEVAR (struct onepart_aux,
					VAR_LOC_1PAUX (var), allocsize);
      /* If the reallocation moves the onepaux structure, the
	 back-pointer to BACKLINKS in the first list member will still
	 point to its old location.  Adjust it.  */
      if (VAR_LOC_DEP_LST (var))
	VAR_LOC_DEP_LST (var)->pprev = VAR_LOC_DEP_LSTP (var);
    }
  else
    {
      VAR_LOC_1PAUX (var) = XNEWVAR (struct onepart_aux, allocsize);
      *VAR_LOC_DEP_LSTP (var) = NULL;
      VAR_LOC_FROM (var) = NULL;
      VAR_LOC_DEPTH (var).complexity = 0;
      VAR_LOC_DEPTH (var).entryvals = 0;
    }
  VAR_LOC_DEP_VEC (var)->embedded_init (count);
}

/* Remove all entries from the vector of active dependencies of VAR,
   removing them from the back-links lists too.  */

static void
loc_exp_dep_clear (variable *var)
{
  while (VAR_LOC_DEP_VEC (var) && !VAR_LOC_DEP_VEC (var)->is_empty ())
    {
      loc_exp_dep *led = &VAR_LOC_DEP_VEC (var)->last ();
      if (led->next)
	led->next->pprev = led->pprev;
      if (led->pprev)
	*led->pprev = led->next;
      VAR_LOC_DEP_VEC (var)->pop ();
    }
}

/* Insert an active dependency from VAR on X to the vector of
   dependencies, and add the corresponding back-link to X's list of
   back-links in VARS.  */

static void
loc_exp_insert_dep (variable *var, rtx x, variable_table_type *vars)
{
  decl_or_value dv;
  variable *xvar;
  loc_exp_dep *led;

  dv = dv_from_rtx (x);

  /* ??? Build a vector of variables parallel to EXPANDING, to avoid
     an additional look up?  */
  xvar = vars->find_with_hash (dv, dv_htab_hash (dv));

  if (!xvar)
    {
      xvar = variable_from_dropped (dv, NO_INSERT);
      gcc_checking_assert (xvar);
    }

  /* No point in adding the same backlink more than once.  This may
     arise if say the same value appears in two complex expressions in
     the same loc_list, or even more than once in a single
     expression.  */
  if (VAR_LOC_DEP_LST (xvar) && VAR_LOC_DEP_LST (xvar)->dv == var->dv)
    return;

  if (var->onepart == NOT_ONEPART)
    led = new loc_exp_dep;
  else
    {
      loc_exp_dep empty;
      memset (&empty, 0, sizeof (empty));
      VAR_LOC_DEP_VEC (var)->quick_push (empty);
      led = &VAR_LOC_DEP_VEC (var)->last ();
    }
  led->dv = var->dv;
  led->value = x;

  loc_exp_dep_alloc (xvar, 0);
  led->pprev = VAR_LOC_DEP_LSTP (xvar);
  led->next = *led->pprev;
  if (led->next)
    led->next->pprev = &led->next;
  *led->pprev = led;
}

/* Create active dependencies of VAR on COUNT values starting at
   VALUE, and corresponding back-links to the entries in VARS.  Return
   true if we found any pending-recursion results.  */

static bool
loc_exp_dep_set (variable *var, rtx result, rtx *value, int count,
		 variable_table_type *vars)
{
  bool pending_recursion = false;

  gcc_checking_assert (VAR_LOC_DEP_VEC (var) == NULL
		       || VAR_LOC_DEP_VEC (var)->is_empty ());

  /* Set up all dependencies from last_child (as set up at the end of
     the loop above) to the end.  */
  loc_exp_dep_alloc (var, count);

  while (count--)
    {
      rtx x = *value++;

      if (!pending_recursion)
	pending_recursion = !result && VALUE_RECURSED_INTO (x);

      loc_exp_insert_dep (var, x, vars);
    }

  return pending_recursion;
}

/* Notify the back-links of IVAR that are pending recursion that we
   have found a non-NIL value for it, so they are cleared for another
   attempt to compute a current location.  */

static void
notify_dependents_of_resolved_value (variable *ivar, variable_table_type *vars)
{
  loc_exp_dep *led, *next;

  for (led = VAR_LOC_DEP_LST (ivar); led; led = next)
    {
      decl_or_value dv = led->dv;
      variable *var;

      next = led->next;

      if (dv_is_value_p (dv))
	{
	  rtx value = dv_as_value (dv);

	  /* If we have already resolved it, leave it alone.  */
	  if (!VALUE_RECURSED_INTO (value))
	    continue;

	  /* Check that VALUE_RECURSED_INTO, true from the test above,
	     implies NO_LOC_P.  */
	  gcc_checking_assert (NO_LOC_P (value));

	  /* We won't notify variables that are being expanded,
	     because their dependency list is cleared before
	     recursing.  */
	  NO_LOC_P (value) = false;
	  VALUE_RECURSED_INTO (value) = false;

	  gcc_checking_assert (dv_changed_p (dv));
	}
      else
	{
	  gcc_checking_assert (dv_onepart_p (dv) != NOT_ONEPART);
	  if (!dv_changed_p (dv))
	    continue;
      }

      var = vars->find_with_hash (dv, dv_htab_hash (dv));

      if (!var)
	var = variable_from_dropped (dv, NO_INSERT);

      if (var)
	notify_dependents_of_resolved_value (var, vars);

      if (next)
	next->pprev = led->pprev;
      if (led->pprev)
	*led->pprev = next;
      led->next = NULL;
      led->pprev = NULL;
    }
}

static rtx vt_expand_loc_callback (rtx x, bitmap regs,
				   int max_depth, void *data);

/* Return the combined depth, when one sub-expression evaluated to
   BEST_DEPTH and the previous known depth was SAVED_DEPTH.  */

static inline expand_depth
update_depth (expand_depth saved_depth, expand_depth best_depth)
{
  /* If we didn't find anything, stick with what we had.  */
  if (!best_depth.complexity)
    return saved_depth;

  /* If we found hadn't found anything, use the depth of the current
     expression.  Do NOT add one extra level, we want to compute the
     maximum depth among sub-expressions.  We'll increment it later,
     if appropriate.  */
  if (!saved_depth.complexity)
    return best_depth;

  /* Combine the entryval count so that regardless of which one we
     return, the entryval count is accurate.  */
  best_depth.entryvals = saved_depth.entryvals
    = best_depth.entryvals + saved_depth.entryvals;

  if (saved_depth.complexity < best_depth.complexity)
    return best_depth;
  else
    return saved_depth;
}

/* Expand VAR to a location RTX, updating its cur_loc.  Use REGS and
   DATA for cselib expand callback.  If PENDRECP is given, indicate in
   it whether any sub-expression couldn't be fully evaluated because
   it is pending recursion resolution.  */

static inline rtx
vt_expand_var_loc_chain (variable *var, bitmap regs, void *data,
			 bool *pendrecp)
{
  class expand_loc_callback_data *elcd
    = (class expand_loc_callback_data *) data;
  location_chain *loc, *next;
  rtx result = NULL;
  int first_child, result_first_child, last_child;
  bool pending_recursion;
  rtx loc_from = NULL;
  struct elt_loc_list *cloc = NULL;
  expand_depth depth = { 0, 0 }, saved_depth = elcd->depth;
  int wanted_entryvals, found_entryvals = 0;

  /* Clear all backlinks pointing at this, so that we're not notified
     while we're active.  */
  loc_exp_dep_clear (var);

 retry:
  if (var->onepart == ONEPART_VALUE)
    {
      cselib_val *val = CSELIB_VAL_PTR (dv_as_value (var->dv));

      gcc_checking_assert (cselib_preserved_value_p (val));

      cloc = val->locs;
    }

  first_child = result_first_child = last_child
    = elcd->expanding.length ();

  wanted_entryvals = found_entryvals;

  /* Attempt to expand each available location in turn.  */
  for (next = loc = var->n_var_parts ? var->var_part[0].loc_chain : NULL;
       loc || cloc; loc = next)
    {
      result_first_child = last_child;

      if (!loc)
	{
	  loc_from = cloc->loc;
	  next = loc;
	  cloc = cloc->next;
	  if (unsuitable_loc (loc_from))
	    continue;
	}
      else
	{
	  loc_from = loc->loc;
	  next = loc->next;
	}

      gcc_checking_assert (!unsuitable_loc (loc_from));

      elcd->depth.complexity = elcd->depth.entryvals = 0;
      result = cselib_expand_value_rtx_cb (loc_from, regs, EXPR_DEPTH,
					   vt_expand_loc_callback, data);
      last_child = elcd->expanding.length ();

      if (result)
	{
	  depth = elcd->depth;

	  gcc_checking_assert (depth.complexity
			       || result_first_child == last_child);

	  if (last_child - result_first_child != 1)
	    {
	      if (!depth.complexity && GET_CODE (result) == ENTRY_VALUE)
		depth.entryvals++;
	      depth.complexity++;
	    }

	  if (depth.complexity <= EXPR_USE_DEPTH)
	    {
	      if (depth.entryvals <= wanted_entryvals)
		break;
	      else if (!found_entryvals || depth.entryvals < found_entryvals)
		found_entryvals = depth.entryvals;
	    }

	  result = NULL;
	}

      /* Set it up in case we leave the loop.  */
      depth.complexity = depth.entryvals = 0;
      loc_from = NULL;
      result_first_child = first_child;
    }

  if (!loc_from && wanted_entryvals < found_entryvals)
    {
      /* We found entries with ENTRY_VALUEs and skipped them.  Since
	 we could not find any expansions without ENTRY_VALUEs, but we
	 found at least one with them, go back and get an entry with
	 the minimum number ENTRY_VALUE count that we found.  We could
	 avoid looping, but since each sub-loc is already resolved,
	 the re-expansion should be trivial.  ??? Should we record all
	 attempted locs as dependencies, so that we retry the
	 expansion should any of them change, in the hope it can give
	 us a new entry without an ENTRY_VALUE?  */
      elcd->expanding.truncate (first_child);
      goto retry;
    }

  /* Register all encountered dependencies as active.  */
  pending_recursion = loc_exp_dep_set
    (var, result, elcd->expanding.address () + result_first_child,
     last_child - result_first_child, elcd->vars);

  elcd->expanding.truncate (first_child);

  /* Record where the expansion came from.  */
  gcc_checking_assert (!result || !pending_recursion);
  VAR_LOC_FROM (var) = loc_from;
  VAR_LOC_DEPTH (var) = depth;

  gcc_checking_assert (!depth.complexity == !result);

  elcd->depth = update_depth (saved_depth, depth);

  /* Indicate whether any of the dependencies are pending recursion
     resolution.  */
  if (pendrecp)
    *pendrecp = pending_recursion;

  if (!pendrecp || !pending_recursion)
    var->var_part[0].cur_loc = result;

  return result;
}

/* Callback for cselib_expand_value, that looks for expressions
   holding the value in the var-tracking hash tables.  Return X for
   standard processing, anything else is to be used as-is.  */

static rtx
vt_expand_loc_callback (rtx x, bitmap regs,
			int max_depth ATTRIBUTE_UNUSED,
			void *data)
{
  class expand_loc_callback_data *elcd
    = (class expand_loc_callback_data *) data;
  decl_or_value dv;
  variable *var;
  rtx result, subreg;
  bool pending_recursion = false;
  bool from_empty = false;

  switch (GET_CODE (x))
    {
    case SUBREG:
      subreg = cselib_expand_value_rtx_cb (SUBREG_REG (x), regs,
					   EXPR_DEPTH,
					   vt_expand_loc_callback, data);

      if (!subreg)
	return NULL;

      result = simplify_gen_subreg (GET_MODE (x), subreg,
				    GET_MODE (SUBREG_REG (x)),
				    SUBREG_BYTE (x));

      /* Invalid SUBREGs are ok in debug info.  ??? We could try
	 alternate expansions for the VALUE as well.  */
      if (!result && GET_MODE (subreg) != VOIDmode)
	result = gen_rtx_raw_SUBREG (GET_MODE (x), subreg, SUBREG_BYTE (x));

      return result;

    case DEBUG_EXPR:
    case VALUE:
      dv = dv_from_rtx (x);
      break;

    default:
      return x;
    }

  elcd->expanding.safe_push (x);

  /* Check that VALUE_RECURSED_INTO implies NO_LOC_P.  */
  gcc_checking_assert (!VALUE_RECURSED_INTO (x) || NO_LOC_P (x));

  if (NO_LOC_P (x))
    {
      gcc_checking_assert (VALUE_RECURSED_INTO (x) || !dv_changed_p (dv));
      return NULL;
    }

  var = elcd->vars->find_with_hash (dv, dv_htab_hash (dv));

  if (!var)
    {
      from_empty = true;
      var = variable_from_dropped (dv, INSERT);
    }

  gcc_checking_assert (var);

  if (!dv_changed_p (dv))
    {
      gcc_checking_assert (!NO_LOC_P (x));
      gcc_checking_assert (var->var_part[0].cur_loc);
      gcc_checking_assert (VAR_LOC_1PAUX (var));
      gcc_checking_assert (VAR_LOC_1PAUX (var)->depth.complexity);

      elcd->depth = update_depth (elcd->depth, VAR_LOC_1PAUX (var)->depth);

      return var->var_part[0].cur_loc;
    }

  VALUE_RECURSED_INTO (x) = true;
  /* This is tentative, but it makes some tests simpler.  */
  NO_LOC_P (x) = true;

  gcc_checking_assert (var->n_var_parts == 1 || from_empty);

  result = vt_expand_var_loc_chain (var, regs, data, &pending_recursion);

  if (pending_recursion)
    {
      gcc_checking_assert (!result);
      elcd->pending.safe_push (x);
    }
  else
    {
      NO_LOC_P (x) = !result;
      VALUE_RECURSED_INTO (x) = false;
      set_dv_changed (dv, false);

      if (result)
	notify_dependents_of_resolved_value (var, elcd->vars);
    }

  return result;
}

/* While expanding variables, we may encounter recursion cycles
   because of mutual (possibly indirect) dependencies between two
   particular variables (or values), say A and B.  If we're trying to
   expand A when we get to B, which in turn attempts to expand A, if
   we can't find any other expansion for B, we'll add B to this
   pending-recursion stack, and tentatively return NULL for its
   location.  This tentative value will be used for any other
   occurrences of B, unless A gets some other location, in which case
   it will notify B that it is worth another try at computing a
   location for it, and it will use the location computed for A then.
   At the end of the expansion, the tentative NULL locations become
   final for all members of PENDING that didn't get a notification.
   This function performs this finalization of NULL locations.  */

static void
resolve_expansions_pending_recursion (vec<rtx, va_heap> *pending)
{
  while (!pending->is_empty ())
    {
      rtx x = pending->pop ();
      decl_or_value dv;

      if (!VALUE_RECURSED_INTO (x))
	continue;

      gcc_checking_assert (NO_LOC_P (x));
      VALUE_RECURSED_INTO (x) = false;
      dv = dv_from_rtx (x);
      gcc_checking_assert (dv_changed_p (dv));
      set_dv_changed (dv, false);
    }
}

/* Initialize expand_loc_callback_data D with variable hash table V.
   It must be a macro because of alloca (vec stack).  */
#define INIT_ELCD(d, v)						\
  do								\
    {								\
      (d).vars = (v);						\
      (d).depth.complexity = (d).depth.entryvals = 0;		\
    }								\
  while (0)
/* Finalize expand_loc_callback_data D, resolved to location L.  */
#define FINI_ELCD(d, l)						\
  do								\
    {								\
      resolve_expansions_pending_recursion (&(d).pending);	\
      (d).pending.release ();					\
      (d).expanding.release ();					\
								\
      if ((l) && MEM_P (l))					\
	(l) = targetm.delegitimize_address (l);			\
    }								\
  while (0)

/* Expand VALUEs and DEBUG_EXPRs in LOC to a location, using the
   equivalences in VARS, updating their CUR_LOCs in the process.  */

static rtx
vt_expand_loc (rtx loc, variable_table_type *vars)
{
  class expand_loc_callback_data data;
  rtx result;

  if (!MAY_HAVE_DEBUG_BIND_INSNS)
    return loc;

  INIT_ELCD (data, vars);

  result = cselib_expand_value_rtx_cb (loc, scratch_regs, EXPR_DEPTH,
				       vt_expand_loc_callback, &data);

  FINI_ELCD (data, result);

  return result;
}

/* Expand the one-part VARiable to a location, using the equivalences
   in VARS, updating their CUR_LOCs in the process.  */

static rtx
vt_expand_1pvar (variable *var, variable_table_type *vars)
{
  class expand_loc_callback_data data;
  rtx loc;

  gcc_checking_assert (var->onepart && var->n_var_parts == 1);

  if (!dv_changed_p (var->dv))
    return var->var_part[0].cur_loc;

  INIT_ELCD (data, vars);

  loc = vt_expand_var_loc_chain (var, scratch_regs, &data, NULL);

  gcc_checking_assert (data.expanding.is_empty ());

  FINI_ELCD (data, loc);

  return loc;
}

/* Emit the NOTE_INSN_VAR_LOCATION for variable *VARP.  DATA contains
   additional parameters: WHERE specifies whether the note shall be emitted
   before or after instruction INSN.  */

int
emit_note_insn_var_location (variable **varp, emit_note_data *data)
{
  variable *var = *varp;
  rtx_insn *insn = data->insn;
  enum emit_note_where where = data->where;
  variable_table_type *vars = data->vars;
  rtx_note *note;
  rtx note_vl;
  int i, j, n_var_parts;
  bool complete;
  enum var_init_status initialized = VAR_INIT_STATUS_UNINITIALIZED;
  HOST_WIDE_INT last_limit;
  HOST_WIDE_INT offsets[MAX_VAR_PARTS];
  rtx loc[MAX_VAR_PARTS];
  tree decl;
  location_chain *lc;

  gcc_checking_assert (var->onepart == NOT_ONEPART
		       || var->onepart == ONEPART_VDECL);

  decl = dv_as_decl (var->dv);

  complete = true;
  last_limit = 0;
  n_var_parts = 0;
  if (!var->onepart)
    for (i = 0; i < var->n_var_parts; i++)
      if (var->var_part[i].cur_loc == NULL && var->var_part[i].loc_chain)
	var->var_part[i].cur_loc = var->var_part[i].loc_chain->loc;
  for (i = 0; i < var->n_var_parts; i++)
    {
      machine_mode mode, wider_mode;
      rtx loc2;
      HOST_WIDE_INT offset, size, wider_size;

      if (i == 0 && var->onepart)
	{
	  gcc_checking_assert (var->n_var_parts == 1);
	  offset = 0;
	  initialized = VAR_INIT_STATUS_INITIALIZED;
	  loc2 = vt_expand_1pvar (var, vars);
	}
      else
	{
	  if (last_limit < VAR_PART_OFFSET (var, i))
	    {
	      complete = false;
	      break;
	    }
	  else if (last_limit > VAR_PART_OFFSET (var, i))
	    continue;
	  offset = VAR_PART_OFFSET (var, i);
	  loc2 = var->var_part[i].cur_loc;
	  if (loc2 && GET_CODE (loc2) == MEM
	      && GET_CODE (XEXP (loc2, 0)) == VALUE)
	    {
	      rtx depval = XEXP (loc2, 0);

	      loc2 = vt_expand_loc (loc2, vars);

	      if (loc2)
		loc_exp_insert_dep (var, depval, vars);
	    }
	  if (!loc2)
	    {
	      complete = false;
	      continue;
	    }
	  gcc_checking_assert (GET_CODE (loc2) != VALUE);
	  for (lc = var->var_part[i].loc_chain; lc; lc = lc->next)
	    if (var->var_part[i].cur_loc == lc->loc)
	      {
		initialized = lc->init;
		break;
	      }
	  gcc_assert (lc);
	}

      offsets[n_var_parts] = offset;
      if (!loc2)
	{
	  complete = false;
	  continue;
	}
      loc[n_var_parts] = loc2;
      mode = GET_MODE (var->var_part[i].cur_loc);
      if (mode == VOIDmode && var->onepart)
	mode = DECL_MODE (decl);
      /* We ony track subparts of constant-sized objects, since at present
	 there's no representation for polynomial pieces.  */
      if (!GET_MODE_SIZE (mode).is_constant (&size))
	{
	  complete = false;
	  continue;
	}
      last_limit = offsets[n_var_parts] + size;

      /* Attempt to merge adjacent registers or memory.  */
      for (j = i + 1; j < var->n_var_parts; j++)
	if (last_limit <= VAR_PART_OFFSET (var, j))
	  break;
      if (j < var->n_var_parts
	  && GET_MODE_WIDER_MODE (mode).exists (&wider_mode)
	  && GET_MODE_SIZE (wider_mode).is_constant (&wider_size)
	  && var->var_part[j].cur_loc
	  && mode == GET_MODE (var->var_part[j].cur_loc)
	  && (REG_P (loc[n_var_parts]) || MEM_P (loc[n_var_parts]))
	  && last_limit == (var->onepart ? 0 : VAR_PART_OFFSET (var, j))
	  && (loc2 = vt_expand_loc (var->var_part[j].cur_loc, vars))
	  && GET_CODE (loc[n_var_parts]) == GET_CODE (loc2))
	{
	  rtx new_loc = NULL;
	  poly_int64 offset2;

	  if (REG_P (loc[n_var_parts])
	      && hard_regno_nregs (REGNO (loc[n_var_parts]), mode) * 2
		 == hard_regno_nregs (REGNO (loc[n_var_parts]), wider_mode)
	      && end_hard_regno (mode, REGNO (loc[n_var_parts]))
		 == REGNO (loc2))
	    {
	      if (! WORDS_BIG_ENDIAN && ! BYTES_BIG_ENDIAN)
		new_loc = simplify_subreg (wider_mode, loc[n_var_parts],
					   mode, 0);
	      else if (WORDS_BIG_ENDIAN && BYTES_BIG_ENDIAN)
		new_loc = simplify_subreg (wider_mode, loc2, mode, 0);
	      if (new_loc)
		{
		  if (!REG_P (new_loc)
		      || REGNO (new_loc) != REGNO (loc[n_var_parts]))
		    new_loc = NULL;
		  else
		    REG_ATTRS (new_loc) = REG_ATTRS (loc[n_var_parts]);
		}
	    }
	  else if (MEM_P (loc[n_var_parts])
		   && GET_CODE (XEXP (loc2, 0)) == PLUS
		   && REG_P (XEXP (XEXP (loc2, 0), 0))
		   && poly_int_rtx_p (XEXP (XEXP (loc2, 0), 1), &offset2))
	    {
	      poly_int64 end1 = size;
	      rtx base1 = strip_offset_and_add (XEXP (loc[n_var_parts], 0),
						&end1);
	      if (rtx_equal_p (base1, XEXP (XEXP (loc2, 0), 0))
		  && known_eq (end1, offset2))
		new_loc = adjust_address_nv (loc[n_var_parts],
					     wider_mode, 0);
	    }

	  if (new_loc)
	    {
	      loc[n_var_parts] = new_loc;
	      mode = wider_mode;
	      last_limit = offsets[n_var_parts] + wider_size;
	      i = j;
	    }
	}
      ++n_var_parts;
    }
  poly_uint64 type_size_unit
    = tree_to_poly_uint64 (TYPE_SIZE_UNIT (TREE_TYPE (decl)));
  if (maybe_lt (poly_uint64 (last_limit), type_size_unit))
    complete = false;

  if (! flag_var_tracking_uninit)
    initialized = VAR_INIT_STATUS_INITIALIZED;

  note_vl = NULL_RTX;
  if (!complete)
    note_vl = gen_rtx_VAR_LOCATION (VOIDmode, decl, NULL_RTX, initialized);
  else if (n_var_parts == 1)
    {
      rtx expr_list;

      if (offsets[0] || GET_CODE (loc[0]) == PARALLEL)
	expr_list = gen_rtx_EXPR_LIST (VOIDmode, loc[0], GEN_INT (offsets[0]));
      else
	expr_list = loc[0];

      note_vl = gen_rtx_VAR_LOCATION (VOIDmode, decl, expr_list, initialized);
    }
  else if (n_var_parts)
    {
      rtx parallel;

      for (i = 0; i < n_var_parts; i++)
	loc[i]
	  = gen_rtx_EXPR_LIST (VOIDmode, loc[i], GEN_INT (offsets[i]));

      parallel = gen_rtx_PARALLEL (VOIDmode,
				   gen_rtvec_v (n_var_parts, loc));
      note_vl = gen_rtx_VAR_LOCATION (VOIDmode, decl,
				      parallel, initialized);
    }

  if (where != EMIT_NOTE_BEFORE_INSN)
    {
      note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn);
      if (where == EMIT_NOTE_AFTER_CALL_INSN)
	NOTE_DURING_CALL_P (note) = true;
    }
  else
    {
      /* Make sure that the call related notes come first.  */
      while (NEXT_INSN (insn)
	     && NOTE_P (insn)
	     && NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION
	     && NOTE_DURING_CALL_P (insn))
	insn = NEXT_INSN (insn);
      if (NOTE_P (insn)
	  && NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION
	  && NOTE_DURING_CALL_P (insn))
	note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn);
      else
	note = emit_note_before (NOTE_INSN_VAR_LOCATION, insn);
    }
  NOTE_VAR_LOCATION (note) = note_vl;

  set_dv_changed (var->dv, false);
  gcc_assert (var->in_changed_variables);
  var->in_changed_variables = false;
  changed_variables->clear_slot (varp);

  /* Continue traversing the hash table.  */
  return 1;
}

/* While traversing changed_variables, push onto DATA (a stack of RTX
   values) entries that aren't user variables.  */

int
var_track_values_to_stack (variable **slot,
			   vec<rtx, va_heap> *changed_values_stack)
{
  variable *var = *slot;

  if (var->onepart == ONEPART_VALUE)
    changed_values_stack->safe_push (dv_as_value (var->dv));
  else if (var->onepart == ONEPART_DEXPR)
    changed_values_stack->safe_push (DECL_RTL_KNOWN_SET (dv_as_decl (var->dv)));

  return 1;
}

/* Remove from changed_variables the entry whose DV corresponds to
   value or debug_expr VAL.  */
static void
remove_value_from_changed_variables (rtx val)
{
  decl_or_value dv = dv_from_rtx (val);
  variable **slot;
  variable *var;

  slot = changed_variables->find_slot_with_hash (dv, dv_htab_hash (dv),
						NO_INSERT);
  var = *slot;
  var->in_changed_variables = false;
  changed_variables->clear_slot (slot);
}

/* If VAL (a value or debug_expr) has backlinks to variables actively
   dependent on it in HTAB or in CHANGED_VARIABLES, mark them as
   changed, adding to CHANGED_VALUES_STACK any dependencies that may
   have dependencies of their own to notify.  */

static void
notify_dependents_of_changed_value (rtx val, variable_table_type *htab,
				    vec<rtx, va_heap> *changed_values_stack)
{
  variable **slot;
  variable *var;
  loc_exp_dep *led;
  decl_or_value dv = dv_from_rtx (val);

  slot = changed_variables->find_slot_with_hash (dv, dv_htab_hash (dv),
						NO_INSERT);
  if (!slot)
    slot = htab->find_slot_with_hash (dv, dv_htab_hash (dv), NO_INSERT);
  if (!slot)
    slot = dropped_values->find_slot_with_hash (dv, dv_htab_hash (dv),
						NO_INSERT);
  var = *slot;

  while ((led = VAR_LOC_DEP_LST (var)))
    {
      decl_or_value ldv = led->dv;
      variable *ivar;

      /* Deactivate and remove the backlink, as it was “used up”.  It
	 makes no sense to attempt to notify the same entity again:
	 either it will be recomputed and re-register an active
	 dependency, or it will still have the changed mark.  */
      if (led->next)
	led->next->pprev = led->pprev;
      if (led->pprev)
	*led->pprev = led->next;
      led->next = NULL;
      led->pprev = NULL;

      if (dv_changed_p (ldv))
	continue;

      switch (dv_onepart_p (ldv))
	{
	case ONEPART_VALUE:
	case ONEPART_DEXPR:
	  set_dv_changed (ldv, true);
	  changed_values_stack->safe_push (dv_as_rtx (ldv));
	  break;

	case ONEPART_VDECL:
	  ivar = htab->find_with_hash (ldv, dv_htab_hash (ldv));
	  gcc_checking_assert (!VAR_LOC_DEP_LST (ivar));
	  variable_was_changed (ivar, NULL);
	  break;

	case NOT_ONEPART:
	  delete led;
	  ivar = htab->find_with_hash (ldv, dv_htab_hash (ldv));
	  if (ivar)
	    {
	      int i = ivar->n_var_parts;
	      while (i--)
		{
		  rtx loc = ivar->var_part[i].cur_loc;

		  if (loc && GET_CODE (loc) == MEM
		      && XEXP (loc, 0) == val)
		    {
		      variable_was_changed (ivar, NULL);
		      break;
		    }
		}
	    }
	  break;

	default:
	  gcc_unreachable ();
	}
    }
}

/* Take out of changed_variables any entries that don't refer to use
   variables.  Back-propagate change notifications from values and
   debug_exprs to their active dependencies in HTAB or in
   CHANGED_VARIABLES.  */

static void
process_changed_values (variable_table_type *htab)
{
  int i, n;
  rtx val;
  auto_vec<rtx, 20> changed_values_stack;

  /* Move values from changed_variables to changed_values_stack.  */
  changed_variables
    ->traverse <vec<rtx, va_heap>*, var_track_values_to_stack>
      (&changed_values_stack);

  /* Back-propagate change notifications in values while popping
     them from the stack.  */
  for (n = i = changed_values_stack.length ();
       i > 0; i = changed_values_stack.length ())
    {
      val = changed_values_stack.pop ();
      notify_dependents_of_changed_value (val, htab, &changed_values_stack);

      /* This condition will hold when visiting each of the entries
	 originally in changed_variables.  We can't remove them
	 earlier because this could drop the backlinks before we got a
	 chance to use them.  */
      if (i == n)
	{
	  remove_value_from_changed_variables (val);
	  n--;
	}
    }
}

/* Emit NOTE_INSN_VAR_LOCATION note for each variable from a chain
   CHANGED_VARIABLES and delete this chain.  WHERE specifies whether
   the notes shall be emitted before of after instruction INSN.  */

static void
emit_notes_for_changes (rtx_insn *insn, enum emit_note_where where,
			shared_hash *vars)
{
  emit_note_data data;
  variable_table_type *htab = shared_hash_htab (vars);

  if (changed_variables->is_empty ())
    return;

  if (MAY_HAVE_DEBUG_BIND_INSNS)
    process_changed_values (htab);

  data.insn = insn;
  data.where = where;
  data.vars = htab;

  changed_variables
    ->traverse <emit_note_data*, emit_note_insn_var_location> (&data);
}

/* Add variable *SLOT to the chain CHANGED_VARIABLES if it differs from the
   same variable in hash table DATA or is not there at all.  */

int
emit_notes_for_differences_1 (variable **slot, variable_table_type *new_vars)
{
  variable *old_var, *new_var;

  old_var = *slot;
  new_var = new_vars->find_with_hash (old_var->dv, dv_htab_hash (old_var->dv));

  if (!new_var)
    {
      /* Variable has disappeared.  */
      variable *empty_var = NULL;

      if (old_var->onepart == ONEPART_VALUE
	  || old_var->onepart == ONEPART_DEXPR)
	{
	  empty_var = variable_from_dropped (old_var->dv, NO_INSERT);
	  if (empty_var)
	    {
	      gcc_checking_assert (!empty_var->in_changed_variables);
	      if (!VAR_LOC_1PAUX (old_var))
		{
		  VAR_LOC_1PAUX (old_var) = VAR_LOC_1PAUX (empty_var);
		  VAR_LOC_1PAUX (empty_var) = NULL;
		}
	      else
		gcc_checking_assert (!VAR_LOC_1PAUX (empty_var));
	    }
	}

      if (!empty_var)
	{
	  empty_var = onepart_pool_allocate (old_var->onepart);
	  empty_var->dv = old_var->dv;
	  empty_var->refcount = 0;
	  empty_var->n_var_parts = 0;
	  empty_var->onepart = old_var->onepart;
	  empty_var->in_changed_variables = false;
	}

      if (empty_var->onepart)
	{
	  /* Propagate the auxiliary data to (ultimately)
	     changed_variables.  */
	  empty_var->var_part[0].loc_chain = NULL;
	  empty_var->var_part[0].cur_loc = NULL;
	  VAR_LOC_1PAUX (empty_var) = VAR_LOC_1PAUX (old_var);
	  VAR_LOC_1PAUX (old_var) = NULL;
	}
      variable_was_changed (empty_var, NULL);
      /* Continue traversing the hash table.  */
      return 1;
    }
  /* Update cur_loc and one-part auxiliary data, before new_var goes
     through variable_was_changed.  */
  if (old_var != new_var && new_var->onepart)
    {
      gcc_checking_assert (VAR_LOC_1PAUX (new_var) == NULL);
      VAR_LOC_1PAUX (new_var) = VAR_LOC_1PAUX (old_var);
      VAR_LOC_1PAUX (old_var) = NULL;
      new_var->var_part[0].cur_loc = old_var->var_part[0].cur_loc;
    }
  if (variable_different_p (old_var, new_var))
    variable_was_changed (new_var, NULL);

  /* Continue traversing the hash table.  */
  return 1;
}

/* Add variable *SLOT to the chain CHANGED_VARIABLES if it is not in hash
   table DATA.  */

int
emit_notes_for_differences_2 (variable **slot, variable_table_type *old_vars)
{
  variable *old_var, *new_var;

  new_var = *slot;
  old_var = old_vars->find_with_hash (new_var->dv, dv_htab_hash (new_var->dv));
  if (!old_var)
    {
      int i;
      for (i = 0; i < new_var->n_var_parts; i++)
	new_var->var_part[i].cur_loc = NULL;
      variable_was_changed (new_var, NULL);
    }

  /* Continue traversing the hash table.  */
  return 1;
}

/* Emit notes before INSN for differences between dataflow sets OLD_SET and
   NEW_SET.  */

static void
emit_notes_for_differences (rtx_insn *insn, dataflow_set *old_set,
			    dataflow_set *new_set)
{
  shared_hash_htab (old_set->vars)
    ->traverse <variable_table_type *, emit_notes_for_differences_1>
      (shared_hash_htab (new_set->vars));
  shared_hash_htab (new_set->vars)
    ->traverse <variable_table_type *, emit_notes_for_differences_2>
      (shared_hash_htab (old_set->vars));
  emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN, new_set->vars);
}

/* Return the next insn after INSN that is not a NOTE_INSN_VAR_LOCATION.  */

static rtx_insn *
next_non_note_insn_var_location (rtx_insn *insn)
{
  while (insn)
    {
      insn = NEXT_INSN (insn);
      if (insn == 0
	  || !NOTE_P (insn)
	  || NOTE_KIND (insn) != NOTE_INSN_VAR_LOCATION)
	break;
    }

  return insn;
}

/* Emit the notes for changes of location parts in the basic block BB.  */

static void
emit_notes_in_bb (basic_block bb, dataflow_set *set)
{
  unsigned int i;
  micro_operation *mo;

  dataflow_set_clear (set);
  dataflow_set_copy (set, &VTI (bb)->in);

  FOR_EACH_VEC_ELT (VTI (bb)->mos, i, mo)
    {
      rtx_insn *insn = mo->insn;
      rtx_insn *next_insn = next_non_note_insn_var_location (insn);

      switch (mo->type)
	{
	  case MO_CALL:
	    dataflow_set_clear_at_call (set, insn);
	    emit_notes_for_changes (insn, EMIT_NOTE_AFTER_CALL_INSN, set->vars);
	    {
	      rtx arguments = mo->u.loc, *p = &arguments;
	      while (*p)
		{
		  XEXP (XEXP (*p, 0), 1)
		    = vt_expand_loc (XEXP (XEXP (*p, 0), 1),
				     shared_hash_htab (set->vars));
		  /* If expansion is successful, keep it in the list.  */
		  if (XEXP (XEXP (*p, 0), 1))
		    {
		      XEXP (XEXP (*p, 0), 1)
			= copy_rtx_if_shared (XEXP (XEXP (*p, 0), 1));
		      p = &XEXP (*p, 1);
		    }
		  /* Otherwise, if the following item is data_value for it,
		     drop it too too.  */
		  else if (XEXP (*p, 1)
			   && REG_P (XEXP (XEXP (*p, 0), 0))
			   && MEM_P (XEXP (XEXP (XEXP (*p, 1), 0), 0))
			   && REG_P (XEXP (XEXP (XEXP (XEXP (*p, 1), 0), 0),
					   0))
			   && REGNO (XEXP (XEXP (*p, 0), 0))
			      == REGNO (XEXP (XEXP (XEXP (XEXP (*p, 1), 0),
						    0), 0)))
		    *p = XEXP (XEXP (*p, 1), 1);
		  /* Just drop this item.  */
		  else
		    *p = XEXP (*p, 1);
		}
	      add_reg_note (insn, REG_CALL_ARG_LOCATION, arguments);
	    }
	    break;

	  case MO_USE:
	    {
	      rtx loc = mo->u.loc;

	      if (REG_P (loc))
		var_reg_set (set, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
	      else
		var_mem_set (set, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);

	      emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN, set->vars);
	    }
	    break;

	  case MO_VAL_LOC:
	    {
	      rtx loc = mo->u.loc;
	      rtx val, vloc;
	      tree var;

	      if (GET_CODE (loc) == CONCAT)
		{
		  val = XEXP (loc, 0);
		  vloc = XEXP (loc, 1);
		}
	      else
		{
		  val = NULL_RTX;
		  vloc = loc;
		}

	      var = PAT_VAR_LOCATION_DECL (vloc);

	      clobber_variable_part (set, NULL_RTX,
				     dv_from_decl (var), 0, NULL_RTX);
	      if (val)
		{
		  if (VAL_NEEDS_RESOLUTION (loc))
		    val_resolve (set, val, PAT_VAR_LOCATION_LOC (vloc), insn);
		  set_variable_part (set, val, dv_from_decl (var), 0,
				     VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
				     INSERT);
		}
	      else if (!VAR_LOC_UNKNOWN_P (PAT_VAR_LOCATION_LOC (vloc)))
		set_variable_part (set, PAT_VAR_LOCATION_LOC (vloc),
				   dv_from_decl (var), 0,
				   VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
				   INSERT);

	      emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN, set->vars);
	    }
	    break;

	  case MO_VAL_USE:
	    {
	      rtx loc = mo->u.loc;
	      rtx val, vloc, uloc;

	      vloc = uloc = XEXP (loc, 1);
	      val = XEXP (loc, 0);

	      if (GET_CODE (val) == CONCAT)
		{
		  uloc = XEXP (val, 1);
		  val = XEXP (val, 0);
		}

	      if (VAL_NEEDS_RESOLUTION (loc))
		val_resolve (set, val, vloc, insn);
	      else
		val_store (set, val, uloc, insn, false);

	      if (VAL_HOLDS_TRACK_EXPR (loc))
		{
		  if (GET_CODE (uloc) == REG)
		    var_reg_set (set, uloc, VAR_INIT_STATUS_UNINITIALIZED,
				 NULL);
		  else if (GET_CODE (uloc) == MEM)
		    var_mem_set (set, uloc, VAR_INIT_STATUS_UNINITIALIZED,
				 NULL);
		}

	      emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN, set->vars);
	    }
	    break;

	  case MO_VAL_SET:
	    {
	      rtx loc = mo->u.loc;
	      rtx val, vloc, uloc;
	      rtx dstv, srcv;

	      vloc = loc;
	      uloc = XEXP (vloc, 1);
	      val = XEXP (vloc, 0);
	      vloc = uloc;

	      if (GET_CODE (uloc) == SET)
		{
		  dstv = SET_DEST (uloc);
		  srcv = SET_SRC (uloc);
		}
	      else
		{
		  dstv = uloc;
		  srcv = NULL;
		}

	      if (GET_CODE (val) == CONCAT)
		{
		  dstv = vloc = XEXP (val, 1);
		  val = XEXP (val, 0);
		}

	      if (GET_CODE (vloc) == SET)
		{
		  srcv = SET_SRC (vloc);

		  gcc_assert (val != srcv);
		  gcc_assert (vloc == uloc || VAL_NEEDS_RESOLUTION (loc));

		  dstv = vloc = SET_DEST (vloc);

		  if (VAL_NEEDS_RESOLUTION (loc))
		    val_resolve (set, val, srcv, insn);
		}
	      else if (VAL_NEEDS_RESOLUTION (loc))
		{
		  gcc_assert (GET_CODE (uloc) == SET
			      && GET_CODE (SET_SRC (uloc)) == REG);
		  val_resolve (set, val, SET_SRC (uloc), insn);
		}

	      if (VAL_HOLDS_TRACK_EXPR (loc))
		{
		  if (VAL_EXPR_IS_CLOBBERED (loc))
		    {
		      if (REG_P (uloc))
			var_reg_delete (set, uloc, true);
		      else if (MEM_P (uloc))
			{
			  gcc_assert (MEM_P (dstv));
			  gcc_assert (MEM_ATTRS (dstv) == MEM_ATTRS (uloc));
			  var_mem_delete (set, dstv, true);
			}
		    }
		  else
		    {
		      bool copied_p = VAL_EXPR_IS_COPIED (loc);
		      rtx src = NULL, dst = uloc;
		      enum var_init_status status = VAR_INIT_STATUS_INITIALIZED;

		      if (GET_CODE (uloc) == SET)
			{
			  src = SET_SRC (uloc);
			  dst = SET_DEST (uloc);
			}

		      if (copied_p)
			{
			  status = find_src_status (set, src);

			  src = find_src_set_src (set, src);
			}

		      if (REG_P (dst))
			var_reg_delete_and_set (set, dst, !copied_p,
						status, srcv);
		      else if (MEM_P (dst))
			{
			  gcc_assert (MEM_P (dstv));
			  gcc_assert (MEM_ATTRS (dstv) == MEM_ATTRS (dst));
			  var_mem_delete_and_set (set, dstv, !copied_p,
						  status, srcv);
			}
		    }
		}
	      else if (REG_P (uloc))
		var_regno_delete (set, REGNO (uloc));
	      else if (MEM_P (uloc))
		{
		  gcc_checking_assert (GET_CODE (vloc) == MEM);
		  gcc_checking_assert (vloc == dstv);
		  if (vloc != dstv)
		    clobber_overlapping_mems (set, vloc);
		}

	      val_store (set, val, dstv, insn, true);

	      emit_notes_for_changes (next_insn, EMIT_NOTE_BEFORE_INSN,
				      set->vars);
	    }
	    break;

	  case MO_SET:
	    {
	      rtx loc = mo->u.loc;
	      rtx set_src = NULL;

	      if (GET_CODE (loc) == SET)
		{
		  set_src = SET_SRC (loc);
		  loc = SET_DEST (loc);
		}

	      if (REG_P (loc))
		var_reg_delete_and_set (set, loc, true, VAR_INIT_STATUS_INITIALIZED,
					set_src);
	      else
		var_mem_delete_and_set (set, loc, true, VAR_INIT_STATUS_INITIALIZED,
					set_src);

	      emit_notes_for_changes (next_insn, EMIT_NOTE_BEFORE_INSN,
				      set->vars);
	    }
	    break;

	  case MO_COPY:
	    {
	      rtx loc = mo->u.loc;
	      enum var_init_status src_status;
	      rtx set_src = NULL;

	      if (GET_CODE (loc) == SET)
		{
		  set_src = SET_SRC (loc);
		  loc = SET_DEST (loc);
		}

	      src_status = find_src_status (set, set_src);
	      set_src = find_src_set_src (set, set_src);

	      if (REG_P (loc))
		var_reg_delete_and_set (set, loc, false, src_status, set_src);
	      else
		var_mem_delete_and_set (set, loc, false, src_status, set_src);

	      emit_notes_for_changes (next_insn, EMIT_NOTE_BEFORE_INSN,
				      set->vars);
	    }
	    break;

	  case MO_USE_NO_VAR:
	    {
	      rtx loc = mo->u.loc;

	      if (REG_P (loc))
		var_reg_delete (set, loc, false);
	      else
		var_mem_delete (set, loc, false);

	      emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN, set->vars);
	    }
	    break;

	  case MO_CLOBBER:
	    {
	      rtx loc = mo->u.loc;

	      if (REG_P (loc))
		var_reg_delete (set, loc, true);
	      else
		var_mem_delete (set, loc, true);

	      emit_notes_for_changes (next_insn, EMIT_NOTE_BEFORE_INSN,
				      set->vars);
	    }
	    break;

	  case MO_ADJUST:
	    set->stack_adjust += mo->u.adjust;
	    break;
	}
    }
}

/* Emit notes for the whole function.  */

static void
vt_emit_notes (void)
{
  basic_block bb;
  dataflow_set cur;

  gcc_assert (changed_variables->is_empty ());

  /* Free memory occupied by the out hash tables, as they aren't used
     anymore.  */
  FOR_EACH_BB_FN (bb, cfun)
    dataflow_set_clear (&VTI (bb)->out);

  /* Enable emitting notes by functions (mainly by set_variable_part and
     delete_variable_part).  */
  emit_notes = true;

  if (MAY_HAVE_DEBUG_BIND_INSNS)
    dropped_values = new variable_table_type (cselib_get_next_uid () * 2);

  dataflow_set_init (&cur);

  FOR_EACH_BB_FN (bb, cfun)
    {
      /* Emit the notes for changes of variable locations between two
	 subsequent basic blocks.  */
      emit_notes_for_differences (BB_HEAD (bb), &cur, &VTI (bb)->in);

      if (MAY_HAVE_DEBUG_BIND_INSNS)
	local_get_addr_cache = new hash_map<rtx, rtx>;

      /* Emit the notes for the changes in the basic block itself.  */
      emit_notes_in_bb (bb, &cur);

      if (MAY_HAVE_DEBUG_BIND_INSNS)
	delete local_get_addr_cache;
      local_get_addr_cache = NULL;

      /* Free memory occupied by the in hash table, we won't need it
	 again.  */
      dataflow_set_clear (&VTI (bb)->in);
    }

  if (flag_checking)
    shared_hash_htab (cur.vars)
      ->traverse <variable_table_type *, emit_notes_for_differences_1>
	(shared_hash_htab (empty_shared_hash));

  dataflow_set_destroy (&cur);

  if (MAY_HAVE_DEBUG_BIND_INSNS)
    delete dropped_values;
  dropped_values = NULL;

  emit_notes = false;
}

/* If there is a declaration and offset associated with register/memory RTL
   assign declaration to *DECLP and offset to *OFFSETP, and return true.  */

static bool
vt_get_decl_and_offset (rtx rtl, tree *declp, poly_int64 *offsetp)
{
  if (REG_P (rtl))
    {
      if (REG_ATTRS (rtl))
	{
	  *declp = REG_EXPR (rtl);
	  *offsetp = REG_OFFSET (rtl);
	  return true;
	}
    }
  else if (GET_CODE (rtl) == PARALLEL)
    {
      tree decl = NULL_TREE;
      HOST_WIDE_INT offset = MAX_VAR_PARTS;
      int len = XVECLEN (rtl, 0), i;

      for (i = 0; i < len; i++)
	{
	  rtx reg = XEXP (XVECEXP (rtl, 0, i), 0);
	  if (!REG_P (reg) || !REG_ATTRS (reg))
	    break;
	  if (!decl)
	    decl = REG_EXPR (reg);
	  if (REG_EXPR (reg) != decl)
	    break;
	  HOST_WIDE_INT this_offset;
	  if (!track_offset_p (REG_OFFSET (reg), &this_offset))
	    break;
	  offset = MIN (offset, this_offset);
	}

      if (i == len)
	{
	  *declp = decl;
	  *offsetp = offset;
	  return true;
	}
    }
  else if (MEM_P (rtl))
    {
      if (MEM_ATTRS (rtl))
	{
	  *declp = MEM_EXPR (rtl);
	  *offsetp = int_mem_offset (rtl);
	  return true;
	}
    }
  return false;
}

/* Record the value for the ENTRY_VALUE of RTL as a global equivalence
   of VAL.  */

static void
record_entry_value (cselib_val *val, rtx rtl)
{
  rtx ev = gen_rtx_ENTRY_VALUE (GET_MODE (rtl));

  ENTRY_VALUE_EXP (ev) = rtl;

  cselib_add_permanent_equiv (val, ev, get_insns ());
}

/* Insert function parameter PARM in IN and OUT sets of ENTRY_BLOCK.  */

static void
vt_add_function_parameter (tree parm)
{
  rtx decl_rtl = DECL_RTL_IF_SET (parm);
  rtx incoming = DECL_INCOMING_RTL (parm);
  tree decl;
  machine_mode mode;
  poly_int64 offset;
  dataflow_set *out;
  decl_or_value dv;
  bool incoming_ok = true;

  if (TREE_CODE (parm) != PARM_DECL)
    return;

  if (!decl_rtl || !incoming)
    return;

  if (GET_MODE (decl_rtl) == BLKmode || GET_MODE (incoming) == BLKmode)
    return;

  /* If there is a DRAP register or a pseudo in internal_arg_pointer,
     rewrite the incoming location of parameters passed on the stack
     into MEMs based on the argument pointer, so that incoming doesn't
     depend on a pseudo.  */
  poly_int64 incoming_offset = 0;
  if (MEM_P (incoming)
      && (strip_offset (XEXP (incoming, 0), &incoming_offset)
	  == crtl->args.internal_arg_pointer))
    {
      HOST_WIDE_INT off = -FIRST_PARM_OFFSET (current_function_decl);
      incoming
	= replace_equiv_address_nv (incoming,
				    plus_constant (Pmode,
						   arg_pointer_rtx,
						   off + incoming_offset));
    }

#ifdef HAVE_window_save
  /* DECL_INCOMING_RTL uses the INCOMING_REGNO of parameter registers.
     If the target machine has an explicit window save instruction, the
     actual entry value is the corresponding OUTGOING_REGNO instead.  */
  if (HAVE_window_save && !crtl->uses_only_leaf_regs)
    {
      if (REG_P (incoming)
	  && HARD_REGISTER_P (incoming)
	  && OUTGOING_REGNO (REGNO (incoming)) != REGNO (incoming))
	{
	  parm_reg p;
	  p.incoming = incoming;
	  incoming
	    = gen_rtx_REG_offset (incoming, GET_MODE (incoming),
				  OUTGOING_REGNO (REGNO (incoming)), 0);
	  p.outgoing = incoming;
	  vec_safe_push (windowed_parm_regs, p);
	}
      else if (GET_CODE (incoming) == PARALLEL)
	{
	  rtx outgoing
	    = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (XVECLEN (incoming, 0)));
	  int i;

	  for (i = 0; i < XVECLEN (incoming, 0); i++)
	    {
	      rtx reg = XEXP (XVECEXP (incoming, 0, i), 0);
	      parm_reg p;
	      p.incoming = reg;
	      reg = gen_rtx_REG_offset (reg, GET_MODE (reg),
					OUTGOING_REGNO (REGNO (reg)), 0);
	      p.outgoing = reg;
	      XVECEXP (outgoing, 0, i)
		= gen_rtx_EXPR_LIST (VOIDmode, reg,
				     XEXP (XVECEXP (incoming, 0, i), 1));
	      vec_safe_push (windowed_parm_regs, p);
	    }

	  incoming = outgoing;
	}
      else if (MEM_P (incoming)
	       && REG_P (XEXP (incoming, 0))
	       && HARD_REGISTER_P (XEXP (incoming, 0)))
	{
	  rtx reg = XEXP (incoming, 0);
	  if (OUTGOING_REGNO (REGNO (reg)) != REGNO (reg))
	    {
	      parm_reg p;
	      p.incoming = reg;
	      reg = gen_raw_REG (GET_MODE (reg), OUTGOING_REGNO (REGNO (reg)));
	      p.outgoing = reg;
	      vec_safe_push (windowed_parm_regs, p);
	      incoming = replace_equiv_address_nv (incoming, reg);
	    }
	}
    }
#endif

  if (!vt_get_decl_and_offset (incoming, &decl, &offset))
    {
      incoming_ok = false;
      if (MEM_P (incoming))
	{
	  /* This means argument is passed by invisible reference.  */
	  offset = 0;
	  decl = parm;
	}
      else
	{
	  if (!vt_get_decl_and_offset (decl_rtl, &decl, &offset))
	    return;
	  offset += byte_lowpart_offset (GET_MODE (incoming),
					 GET_MODE (decl_rtl));
	}
    }

  if (!decl)
    return;

  if (parm != decl)
    {
      /* If that DECL_RTL wasn't a pseudo that got spilled to
	 memory, bail out.  Otherwise, the spill slot sharing code
	 will force the memory to reference spill_slot_decl (%sfp),
	 so we don't match above.  That's ok, the pseudo must have
	 referenced the entire parameter, so just reset OFFSET.  */
      if (decl != get_spill_slot_decl (false))
        return;
      offset = 0;
    }

  HOST_WIDE_INT const_offset;
  if (!track_loc_p (incoming, parm, offset, false, &mode, &const_offset))
    return;

  out = &VTI (ENTRY_BLOCK_PTR_FOR_FN (cfun))->out;

  dv = dv_from_decl (parm);

  if (target_for_debug_bind (parm)
      /* We can't deal with these right now, because this kind of
	 variable is single-part.  ??? We could handle parallels
	 that describe multiple locations for the same single
	 value, but ATM we don't.  */
      && GET_CODE (incoming) != PARALLEL)
    {
      cselib_val *val;
      rtx lowpart;

      /* ??? We shouldn't ever hit this, but it may happen because
	 arguments passed by invisible reference aren't dealt with
	 above: incoming-rtl will have Pmode rather than the
	 expected mode for the type.  */
      if (const_offset)
	return;

      lowpart = var_lowpart (mode, incoming);
      if (!lowpart)
	return;

      val = cselib_lookup_from_insn (lowpart, mode, true,
				     VOIDmode, get_insns ());

      /* ??? Float-typed values in memory are not handled by
	 cselib.  */
      if (val)
	{
	  preserve_value (val);
	  set_variable_part (out, val->val_rtx, dv, const_offset,
			     VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
	  dv = dv_from_value (val->val_rtx);
	}

      if (MEM_P (incoming))
	{
	  val = cselib_lookup_from_insn (XEXP (incoming, 0), mode, true,
					 VOIDmode, get_insns ());
	  if (val)
	    {
	      preserve_value (val);
	      incoming = replace_equiv_address_nv (incoming, val->val_rtx);
	    }
	}
    }

  if (REG_P (incoming))
    {
      incoming = var_lowpart (mode, incoming);
      gcc_assert (REGNO (incoming) < FIRST_PSEUDO_REGISTER);
      attrs_list_insert (&out->regs[REGNO (incoming)], dv, const_offset,
			 incoming);
      set_variable_part (out, incoming, dv, const_offset,
			 VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
      if (dv_is_value_p (dv))
	{
	  record_entry_value (CSELIB_VAL_PTR (dv_as_value (dv)), incoming);
	  if (TREE_CODE (TREE_TYPE (parm)) == REFERENCE_TYPE
	      && INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (parm))))
	    {
	      machine_mode indmode
		= TYPE_MODE (TREE_TYPE (TREE_TYPE (parm)));
	      rtx mem = gen_rtx_MEM (indmode, incoming);
	      cselib_val *val = cselib_lookup_from_insn (mem, indmode, true,
							 VOIDmode,
							 get_insns ());
	      if (val)
		{
		  preserve_value (val);
		  record_entry_value (val, mem);
		  set_variable_part (out, mem, dv_from_value (val->val_rtx), 0,
				     VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
		}
	    }

	  if (GET_MODE_CLASS (mode) == MODE_INT)
	    {
	      machine_mode wider_mode_iter;
	      FOR_EACH_WIDER_MODE (wider_mode_iter, mode)
		{
		  if (!HWI_COMPUTABLE_MODE_P (wider_mode_iter))
		    break;
		  rtx wider_reg
		    = gen_rtx_REG (wider_mode_iter, REGNO (incoming));
		  cselib_val *wider_val
		    = cselib_lookup_from_insn (wider_reg, wider_mode_iter, 1,
					       VOIDmode, get_insns ());
		  preserve_value (wider_val);
		  record_entry_value (wider_val, wider_reg);
		}
	    }
	}
    }
  else if (GET_CODE (incoming) == PARALLEL && !dv_onepart_p (dv))
    {
      int i;

      /* The following code relies on vt_get_decl_and_offset returning true for
	 incoming, which might not be always the case.  */
      if (!incoming_ok)
	return;
      for (i = 0; i < XVECLEN (incoming, 0); i++)
	{
	  rtx reg = XEXP (XVECEXP (incoming, 0, i), 0);
	  /* vt_get_decl_and_offset has already checked that the offset
	     is a valid variable part.  */
	  const_offset = get_tracked_reg_offset (reg);
	  gcc_assert (REGNO (reg) < FIRST_PSEUDO_REGISTER);
	  attrs_list_insert (&out->regs[REGNO (reg)], dv, const_offset, reg);
	  set_variable_part (out, reg, dv, const_offset,
			     VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
	}
    }
  else if (MEM_P (incoming))
    {
      incoming = var_lowpart (mode, incoming);
      set_variable_part (out, incoming, dv, const_offset,
			 VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
    }
}

/* Insert function parameters to IN and OUT sets of ENTRY_BLOCK.  */

static void
vt_add_function_parameters (void)
{
  tree parm;

  for (parm = DECL_ARGUMENTS (current_function_decl);
       parm; parm = DECL_CHAIN (parm))
    vt_add_function_parameter (parm);

  if (DECL_HAS_VALUE_EXPR_P (DECL_RESULT (current_function_decl)))
    {
      tree vexpr = DECL_VALUE_EXPR (DECL_RESULT (current_function_decl));

      if (TREE_CODE (vexpr) == INDIRECT_REF)
	vexpr = TREE_OPERAND (vexpr, 0);

      if (TREE_CODE (vexpr) == PARM_DECL
	  && DECL_ARTIFICIAL (vexpr)
	  && !DECL_IGNORED_P (vexpr)
	  && DECL_NAMELESS (vexpr))
	vt_add_function_parameter (vexpr);
    }
}

/* Initialize cfa_base_rtx, create a preserved VALUE for it and
   ensure it isn't flushed during cselib_reset_table.
   Can be called only if frame_pointer_rtx resp. arg_pointer_rtx
   has been eliminated.  */

static void
vt_init_cfa_base (void)
{
  cselib_val *val;

#ifdef FRAME_POINTER_CFA_OFFSET
  cfa_base_rtx = frame_pointer_rtx;
  cfa_base_offset = -FRAME_POINTER_CFA_OFFSET (current_function_decl);
#else
  cfa_base_rtx = arg_pointer_rtx;
  cfa_base_offset = -ARG_POINTER_CFA_OFFSET (current_function_decl);
#endif
  if (cfa_base_rtx == hard_frame_pointer_rtx
      || !fixed_regs[REGNO (cfa_base_rtx)])
    {
      cfa_base_rtx = NULL_RTX;
      return;
    }
  if (!MAY_HAVE_DEBUG_BIND_INSNS)
    return;

  /* Tell alias analysis that cfa_base_rtx should share
     find_base_term value with stack pointer or hard frame pointer.  */
  if (!frame_pointer_needed)
    vt_equate_reg_base_value (cfa_base_rtx, stack_pointer_rtx);
  else if (!crtl->stack_realign_tried)
    vt_equate_reg_base_value (cfa_base_rtx, hard_frame_pointer_rtx);

  val = cselib_lookup_from_insn (cfa_base_rtx, GET_MODE (cfa_base_rtx), 1,
				 VOIDmode, get_insns ());
  preserve_value (val);
  cselib_preserve_cfa_base_value (val, REGNO (cfa_base_rtx));
}

/* Reemit INSN, a MARKER_DEBUG_INSN, as a note.  */

static rtx_insn *
reemit_marker_as_note (rtx_insn *insn)
{
  gcc_checking_assert (DEBUG_MARKER_INSN_P (insn));

  enum insn_note kind = INSN_DEBUG_MARKER_KIND (insn);

  switch (kind)
    {
    case NOTE_INSN_BEGIN_STMT:
    case NOTE_INSN_INLINE_ENTRY:
      {
	rtx_insn *note = NULL;
	if (cfun->debug_nonbind_markers)
	  {
	    note = emit_note_before (kind, insn);
	    NOTE_MARKER_LOCATION (note) = INSN_LOCATION (insn);
	  }
	delete_insn (insn);
	return note;
      }

    default:
      gcc_unreachable ();
    }
}

/* Allocate and initialize the data structures for variable tracking
   and parse the RTL to get the micro operations.  */

static bool
vt_initialize (void)
{
  basic_block bb;
  poly_int64 fp_cfa_offset = -1;

  alloc_aux_for_blocks (sizeof (variable_tracking_info));

  empty_shared_hash = shared_hash_pool.allocate ();
  empty_shared_hash->refcount = 1;
  empty_shared_hash->htab = new variable_table_type (1);
  changed_variables = new variable_table_type (10);

  /* Init the IN and OUT sets.  */
  FOR_ALL_BB_FN (bb, cfun)
    {
      VTI (bb)->visited = false;
      VTI (bb)->flooded = false;
      dataflow_set_init (&VTI (bb)->in);
      dataflow_set_init (&VTI (bb)->out);
      VTI (bb)->permp = NULL;
    }

  if (MAY_HAVE_DEBUG_BIND_INSNS)
    {
      cselib_init (CSELIB_RECORD_MEMORY | CSELIB_PRESERVE_CONSTANTS);
      scratch_regs = BITMAP_ALLOC (NULL);
      preserved_values.create (256);
      global_get_addr_cache = new hash_map<rtx, rtx>;
    }
  else
    {
      scratch_regs = NULL;
      global_get_addr_cache = NULL;
    }

  if (MAY_HAVE_DEBUG_BIND_INSNS)
    {
      rtx reg, expr;
      int ofst;
      cselib_val *val;

#ifdef FRAME_POINTER_CFA_OFFSET
      reg = frame_pointer_rtx;
      ofst = FRAME_POINTER_CFA_OFFSET (current_function_decl);
#else
      reg = arg_pointer_rtx;
      ofst = ARG_POINTER_CFA_OFFSET (current_function_decl);
#endif

      ofst -= INCOMING_FRAME_SP_OFFSET;

      val = cselib_lookup_from_insn (reg, GET_MODE (reg), 1,
				     VOIDmode, get_insns ());
      preserve_value (val);
      if (reg != hard_frame_pointer_rtx && fixed_regs[REGNO (reg)])
	cselib_preserve_cfa_base_value (val, REGNO (reg));
      if (ofst)
	{
	  cselib_val *valsp
	    = cselib_lookup_from_insn (stack_pointer_rtx,
				       GET_MODE (stack_pointer_rtx), 1,
				       VOIDmode, get_insns ());
	  preserve_value (valsp);
	  expr = plus_constant (GET_MODE (reg), reg, ofst);
	  /* This cselib_add_permanent_equiv call needs to be done before
	     the other cselib_add_permanent_equiv a few lines later,
	     because after that one is done, cselib_lookup on this expr
	     will due to the cselib SP_DERIVED_VALUE_P optimizations
	     return valsp and so no permanent equivalency will be added.  */
	  cselib_add_permanent_equiv (valsp, expr, get_insns ());
	}

      expr = plus_constant (GET_MODE (stack_pointer_rtx),
			    stack_pointer_rtx, -ofst);
      cselib_add_permanent_equiv (val, expr, get_insns ());
    }

  /* In order to factor out the adjustments made to the stack pointer or to
     the hard frame pointer and thus be able to use DW_OP_fbreg operations
     instead of individual location lists, we're going to rewrite MEMs based
     on them into MEMs based on the CFA by de-eliminating stack_pointer_rtx
     or hard_frame_pointer_rtx to the virtual CFA pointer frame_pointer_rtx
     resp. arg_pointer_rtx.  We can do this either when there is no frame
     pointer in the function and stack adjustments are consistent for all
     basic blocks or when there is a frame pointer and no stack realignment.
     But we first have to check that frame_pointer_rtx resp. arg_pointer_rtx
     has been eliminated.  */
  if (!frame_pointer_needed)
    {
      rtx reg, elim;

      if (!vt_stack_adjustments ())
	return false;

#ifdef FRAME_POINTER_CFA_OFFSET
      reg = frame_pointer_rtx;
#else
      reg = arg_pointer_rtx;
#endif
      elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
      if (elim != reg)
	{
	  if (GET_CODE (elim) == PLUS)
	    elim = XEXP (elim, 0);
	  if (elim == stack_pointer_rtx)
	    vt_init_cfa_base ();
	}
    }
  else if (!crtl->stack_realign_tried)
    {
      rtx reg, elim;

#ifdef FRAME_POINTER_CFA_OFFSET
      reg = frame_pointer_rtx;
      fp_cfa_offset = FRAME_POINTER_CFA_OFFSET (current_function_decl);
#else
      reg = arg_pointer_rtx;
      fp_cfa_offset = ARG_POINTER_CFA_OFFSET (current_function_decl);
#endif
      elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
      if (elim != reg)
	{
	  if (GET_CODE (elim) == PLUS)
	    {
	      fp_cfa_offset -= rtx_to_poly_int64 (XEXP (elim, 1));
	      elim = XEXP (elim, 0);
	    }
	  if (elim != hard_frame_pointer_rtx)
	    fp_cfa_offset = -1;
	}
      else
	fp_cfa_offset = -1;
    }

  /* If the stack is realigned and a DRAP register is used, we're going to
     rewrite MEMs based on it representing incoming locations of parameters
     passed on the stack into MEMs based on the argument pointer.  Although
     we aren't going to rewrite other MEMs, we still need to initialize the
     virtual CFA pointer in order to ensure that the argument pointer will
     be seen as a constant throughout the function.

     ??? This doesn't work if FRAME_POINTER_CFA_OFFSET is defined.  */
  else if (stack_realign_drap)
    {
      rtx reg, elim;

#ifdef FRAME_POINTER_CFA_OFFSET
      reg = frame_pointer_rtx;
#else
      reg = arg_pointer_rtx;
#endif
      elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
      if (elim != reg)
	{
	  if (GET_CODE (elim) == PLUS)
	    elim = XEXP (elim, 0);
	  if (elim == hard_frame_pointer_rtx)
	    vt_init_cfa_base ();
	}
    }

  hard_frame_pointer_adjustment = -1;

  vt_add_function_parameters ();

  bool record_sp_value = false;
  FOR_EACH_BB_FN (bb, cfun)
    {
      rtx_insn *insn;
      basic_block first_bb, last_bb;

      if (MAY_HAVE_DEBUG_BIND_INSNS)
	{
	  cselib_record_sets_hook = add_with_sets;
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file, "first value: %i\n",
		     cselib_get_next_uid ());
	}

      if (MAY_HAVE_DEBUG_BIND_INSNS
	  && cfa_base_rtx
	  && !frame_pointer_needed
	  && record_sp_value)
	cselib_record_sp_cfa_base_equiv (-cfa_base_offset
					 - VTI (bb)->in.stack_adjust,
					 BB_HEAD (bb));
      record_sp_value = true;

      first_bb = bb;
      for (;;)
	{
	  edge e;
	  if (bb->next_bb == EXIT_BLOCK_PTR_FOR_FN (cfun)
	      || ! single_pred_p (bb->next_bb))
	    break;
	  e = find_edge (bb, bb->next_bb);
	  if (! e || (e->flags & EDGE_FALLTHRU) == 0)
	    break;
	  bb = bb->next_bb;
	}
      last_bb = bb;

      /* Add the micro-operations to the vector.  */
      FOR_BB_BETWEEN (bb, first_bb, last_bb->next_bb, next_bb)
	{
	  HOST_WIDE_INT offset = VTI (bb)->out.stack_adjust;
	  VTI (bb)->out.stack_adjust = VTI (bb)->in.stack_adjust;

	  rtx_insn *next;
	  FOR_BB_INSNS_SAFE (bb, insn, next)
	    {
	      if (INSN_P (insn))
		{
		  HOST_WIDE_INT pre = 0, post = 0;

		  if (!frame_pointer_needed)
		    {
		      insn_stack_adjust_offset_pre_post (insn, &pre, &post);
		      if (pre)
			{
			  micro_operation mo;
			  mo.type = MO_ADJUST;
			  mo.u.adjust = pre;
			  mo.insn = insn;
			  if (dump_file && (dump_flags & TDF_DETAILS))
			    log_op_type (PATTERN (insn), bb, insn,
					 MO_ADJUST, dump_file);
			  VTI (bb)->mos.safe_push (mo);
			}
		    }

		  cselib_hook_called = false;
		  adjust_insn (bb, insn);

		  if (pre)
		    VTI (bb)->out.stack_adjust += pre;

		  if (DEBUG_MARKER_INSN_P (insn))
		    {
		      reemit_marker_as_note (insn);
		      continue;
		    }

		  if (MAY_HAVE_DEBUG_BIND_INSNS)
		    {
		      if (CALL_P (insn))
			prepare_call_arguments (bb, insn);
		      cselib_process_insn (insn);
		      if (dump_file && (dump_flags & TDF_DETAILS))
			{
			  if (dump_flags & TDF_SLIM)
			    dump_insn_slim (dump_file, insn);
			  else
			    print_rtl_single (dump_file, insn);
			  dump_cselib_table (dump_file);
			}
		    }
		  if (!cselib_hook_called)
		    add_with_sets (insn, 0, 0);
		  cancel_changes (0);

		  if (post)
		    {
		      micro_operation mo;
		      mo.type = MO_ADJUST;
		      mo.u.adjust = post;
		      mo.insn = insn;
		      if (dump_file && (dump_flags & TDF_DETAILS))
			log_op_type (PATTERN (insn), bb, insn,
				     MO_ADJUST, dump_file);
		      VTI (bb)->mos.safe_push (mo);
		      VTI (bb)->out.stack_adjust += post;
		    }

		  if (maybe_ne (fp_cfa_offset, -1)
		      && known_eq (hard_frame_pointer_adjustment, -1)
		      && fp_setter_insn (insn))
		    {
		      vt_init_cfa_base ();
		      hard_frame_pointer_adjustment = fp_cfa_offset;
		      /* Disassociate sp from fp now.  */
		      if (MAY_HAVE_DEBUG_BIND_INSNS)
			{
			  cselib_val *v;
			  cselib_invalidate_rtx (stack_pointer_rtx);
			  v = cselib_lookup (stack_pointer_rtx, Pmode, 1,
					     VOIDmode);
			  if (v && !cselib_preserved_value_p (v))
			    {
			      cselib_set_value_sp_based (v);
			      preserve_value (v);
			    }
			}
		    }
		}
	    }
	  gcc_assert (offset == VTI (bb)->out.stack_adjust);
	}

      bb = last_bb;

      if (MAY_HAVE_DEBUG_BIND_INSNS)
	{
	  cselib_preserve_only_values ();
	  cselib_reset_table (cselib_get_next_uid ());
	  cselib_record_sets_hook = NULL;
	}
    }

  hard_frame_pointer_adjustment = -1;
  VTI (ENTRY_BLOCK_PTR_FOR_FN (cfun))->flooded = true;
  cfa_base_rtx = NULL_RTX;
  return true;
}

/* This is *not* reset after each function.  It gives each
   NOTE_INSN_DELETED_DEBUG_LABEL in the entire compilation
   a unique label number.  */

static int debug_label_num = 1;

/* Remove from the insn stream a single debug insn used for
   variable tracking at assignments.  */

static inline void
delete_vta_debug_insn (rtx_insn *insn)
{
  if (DEBUG_MARKER_INSN_P (insn))
    {
      reemit_marker_as_note (insn);
      return;
    }

  tree decl = INSN_VAR_LOCATION_DECL (insn);
  if (TREE_CODE (decl) == LABEL_DECL
      && DECL_NAME (decl)
      && !DECL_RTL_SET_P (decl))
    {
      PUT_CODE (insn, NOTE);
      NOTE_KIND (insn) = NOTE_INSN_DELETED_DEBUG_LABEL;
      NOTE_DELETED_LABEL_NAME (insn)
	= IDENTIFIER_POINTER (DECL_NAME (decl));
      SET_DECL_RTL (decl, insn);
      CODE_LABEL_NUMBER (insn) = debug_label_num++;
    }
  else
    delete_insn (insn);
}

/* Remove from the insn stream all debug insns used for variable
   tracking at assignments.  USE_CFG should be false if the cfg is no
   longer usable.  */

void
delete_vta_debug_insns (bool use_cfg)
{
  basic_block bb;
  rtx_insn *insn, *next;

  if (!MAY_HAVE_DEBUG_INSNS)
    return;

  if (use_cfg)
    FOR_EACH_BB_FN (bb, cfun)
      {
	FOR_BB_INSNS_SAFE (bb, insn, next)
	  if (DEBUG_INSN_P (insn))
	    delete_vta_debug_insn (insn);
      }
  else
    for (insn = get_insns (); insn; insn = next)
      {
	next = NEXT_INSN (insn);
	if (DEBUG_INSN_P (insn))
	  delete_vta_debug_insn (insn);
      }
}

/* Run a fast, BB-local only version of var tracking, to take care of
   information that we don't do global analysis on, such that not all
   information is lost.  If SKIPPED holds, we're skipping the global
   pass entirely, so we should try to use information it would have
   handled as well..  */

static void
vt_debug_insns_local (bool skipped ATTRIBUTE_UNUSED)
{
  /* ??? Just skip it all for now.  */
  delete_vta_debug_insns (true);
}

/* Free the data structures needed for variable tracking.  */

static void
vt_finalize (void)
{
  basic_block bb;

  FOR_EACH_BB_FN (bb, cfun)
    {
      VTI (bb)->mos.release ();
    }

  FOR_ALL_BB_FN (bb, cfun)
    {
      dataflow_set_destroy (&VTI (bb)->in);
      dataflow_set_destroy (&VTI (bb)->out);
      if (VTI (bb)->permp)
	{
	  dataflow_set_destroy (VTI (bb)->permp);
	  XDELETE (VTI (bb)->permp);
	}
    }
  free_aux_for_blocks ();
  delete empty_shared_hash->htab;
  empty_shared_hash->htab = NULL;
  delete changed_variables;
  changed_variables = NULL;
  attrs_pool.release ();
  var_pool.release ();
  location_chain_pool.release ();
  shared_hash_pool.release ();

  if (MAY_HAVE_DEBUG_BIND_INSNS)
    {
      if (global_get_addr_cache)
	delete global_get_addr_cache;
      global_get_addr_cache = NULL;
      loc_exp_dep_pool.release ();
      valvar_pool.release ();
      preserved_values.release ();
      cselib_finish ();
      BITMAP_FREE (scratch_regs);
      scratch_regs = NULL;
    }

#ifdef HAVE_window_save
  vec_free (windowed_parm_regs);
#endif

  if (vui_vec)
    XDELETEVEC (vui_vec);
  vui_vec = NULL;
  vui_allocated = 0;
}

/* The entry point to variable tracking pass.  */

static inline unsigned int
variable_tracking_main_1 (void)
{
  bool success;

  /* We won't be called as a separate pass if flag_var_tracking is not
     set, but final may call us to turn debug markers into notes.  */
  if ((!flag_var_tracking && MAY_HAVE_DEBUG_INSNS)
      || flag_var_tracking_assignments < 0
      /* Var-tracking right now assumes the IR doesn't contain
	 any pseudos at this point.  */
      || targetm.no_register_allocation)
    {
      delete_vta_debug_insns (true);
      return 0;
    }

  if (!flag_var_tracking)
    return 0;

  if (n_basic_blocks_for_fn (cfun) > 500
      && n_edges_for_fn (cfun) / n_basic_blocks_for_fn (cfun) >= 20)
    {
      vt_debug_insns_local (true);
      return 0;
    }

  if (!vt_initialize ())
    {
      vt_finalize ();
      vt_debug_insns_local (true);
      return 0;
    }

  success = vt_find_locations ();

  if (!success && flag_var_tracking_assignments > 0)
    {
      vt_finalize ();

      delete_vta_debug_insns (true);

      /* This is later restored by our caller.  */
      flag_var_tracking_assignments = 0;

      success = vt_initialize ();
      gcc_assert (success);

      success = vt_find_locations ();
    }

  if (!success)
    {
      vt_finalize ();
      vt_debug_insns_local (false);
      return 0;
    }

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      dump_dataflow_sets ();
      dump_reg_info (dump_file);
      dump_flow_info (dump_file, dump_flags);
    }

  timevar_push (TV_VAR_TRACKING_EMIT);
  vt_emit_notes ();
  timevar_pop (TV_VAR_TRACKING_EMIT);

  vt_finalize ();
  vt_debug_insns_local (false);
  return 0;
}

unsigned int
variable_tracking_main (void)
{
  unsigned int ret;
  int save = flag_var_tracking_assignments;

  ret = variable_tracking_main_1 ();

  flag_var_tracking_assignments = save;

  return ret;
}

namespace {

const pass_data pass_data_variable_tracking =
{
  RTL_PASS, /* type */
  "vartrack", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_VAR_TRACKING, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_variable_tracking : public rtl_opt_pass
{
public:
  pass_variable_tracking (gcc::context *ctxt)
    : rtl_opt_pass (pass_data_variable_tracking, ctxt)
  {}

  /* opt_pass methods: */
  bool gate (function *) final override
    {
      return (flag_var_tracking && !targetm.delay_vartrack);
    }

  unsigned int execute (function *) final override
    {
      return variable_tracking_main ();
    }

}; // class pass_variable_tracking

} // anon namespace

rtl_opt_pass *
make_pass_variable_tracking (gcc::context *ctxt)
{
  return new pass_variable_tracking (ctxt);
}
