/* Variable tracking routines for the GNU compiler.
   Copyright (C) 2002-2016 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 "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 "params.h"
#include "tree-pretty-print.h"
#include "rtl-iter.h"
#include "fibonacci_heap.h"

typedef fibonacci_heap <long, basic_block_def> bb_heap_t;
typedef fibonacci_node <long, basic_block_def> bb_heap_node_t;

/* var-tracking.c 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;
};

/* 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.  */
  vec<loc_exp_dep, va_heap, vl_embed> 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)

/* Macro to access MEM_OFFSET as an HOST_WIDE_INT.  Evaluates MEM twice.  */
#define INT_MEM_OFFSET(mem) (MEM_OFFSET_KNOWN_P (mem) ? MEM_OFFSET (mem) : 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_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 bool same_variable_part_p (rtx, tree, HOST_WIDE_INT);
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 bool vt_get_decl_and_offset (rtx, tree *, HOST_WIDE_INT *);
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 (HOST_WIDE_INT 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 HOST_WIDE_INT hard_frame_pointer_adjustment = -1;

/* Data for adjust_mems callback.  */

struct adjust_mem_data
{
  bool store;
  machine_mode mem_mode;
  HOST_WIDE_INT stack_adjust;
  rtx_expr_list *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:
	    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, machine_mode mode, machine_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 (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)
{
  struct adjust_mem_data *amd = (struct adjust_mem_data *) data;
  rtx mem, addr = loc, tem;
  machine_mode mem_mode_save;
  bool store_save;
  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
	       && 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:
      addr = gen_rtx_PLUS (GET_MODE (loc), XEXP (loc, 0),
			   gen_int_mode (GET_CODE (loc) == PRE_INC
					 ? GET_MODE_SIZE (amd->mem_mode)
					 : -GET_MODE_SIZE (amd->mem_mode),
					 GET_MODE (loc)));
    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);
      tem = gen_rtx_PLUS (GET_MODE (loc), XEXP (loc, 0),
			  gen_int_mode ((GET_CODE (loc) == PRE_INC
					 || GET_CODE (loc) == POST_INC)
					? GET_MODE_SIZE (amd->mem_mode)
					: -GET_MODE_SIZE (amd->mem_mode),
					GET_MODE (loc)));
      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 = alloc_EXPR_LIST (0,
					   gen_rtx_SET (XEXP (loc, 0), tem),
					   amd->side_effects);
      return addr;
    case PRE_MODIFY:
      addr = XEXP (loc, 1);
    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 = alloc_EXPR_LIST (0,
					   gen_rtx_SET (XEXP (loc, 0), tem),
					   amd->side_effects);
      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_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)
	  && (GET_MODE_CLASS (GET_MODE (tem)) == MODE_INT
	      || GET_MODE_CLASS (GET_MODE (tem)) == MODE_PARTIAL_INT)
	  && (GET_MODE_CLASS (GET_MODE (SUBREG_REG (tem))) == MODE_INT
	      || GET_MODE_CLASS (GET_MODE (SUBREG_REG (tem))) == MODE_PARTIAL_INT)
	  && GET_MODE_PRECISION (GET_MODE (tem))
	     < GET_MODE_PRECISION (GET_MODE (SUBREG_REG (tem)))
	  && subreg_lowpart_p (tem)
	  && use_narrower_mode_test (SUBREG_REG (tem), tem))
	return use_narrower_mode (SUBREG_REG (tem), GET_MODE (tem),
				  GET_MODE (SUBREG_REG (tem)));
      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)
{
  struct adjust_mem_data amd;
  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

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

  amd.store = true;
  note_stores (PATTERN (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)
    {
      rtx *pat, new_pat, s;
      int i, oldn, newn;

      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;
      for (s = amd.side_effects, newn = 0; s; newn++)
	s = XEXP (s, 1);
      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;
      for (s = amd.side_effects, i = oldn; i < oldn + newn; i++, s = XEXP (s, 1))
	XVECEXP (new_pat, 0, i) = XEXP (s, 0);
      free_EXPR_LIST_list (&amd.side_effects);
      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_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 && TREE_CODE (decl) == VAR_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);
}

/* 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 = 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 = 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;

  if (clobber)
    {
      tree decl = REG_EXPR (loc);
      HOST_WIDE_INT offset = REG_OFFSET (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 x == (x & -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)
{
  HOST_WIDE_INT ofst = 0;
  machine_mode mode = GET_MODE (oloc);
  rtx loc = oloc;
  rtx x;
  bool retry = true;

  while (retry)
    {
      while (GET_CODE (loc) == PLUS
	     && GET_CODE (XEXP (loc, 1)) == CONST_INT)
	{
	  ofst += INTVAL (XEXP (loc, 1));
	  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 (ofst && GET_CODE (loc) == PLUS
		 && GET_CODE (XEXP (loc, 1)) == CONST_INT)
	    {
	      ofst += INTVAL (XEXP (loc, 1));
	      loc = XEXP (loc, 0);
	    }

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

  /* Add OFST back in.  */
  if (ofst)
    {
      /* Don't build new RTL if we can help it.  */
      if (GET_CODE (oloc) == PLUS
	  && XEXP (oloc, 0) == loc
	  && INTVAL (XEXP (oloc, 1)) == 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 CC0:
    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, accummulating 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 '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 invalidated_regs;

  get_call_reg_set_usage (call_insn, &invalidated_regs,
			  regs_invalidated_by_call);

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

  if (MAY_HAVE_DEBUG_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 (TREE_CODE (expr) != VAR_DECL && 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 (TREE_CODE (realdecl) == VAR_DECL && 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, maxsize;
	      bool reverse;
	      tree innerdecl
		= get_ref_base_and_extent (realdecl, &bitpos, &bitsize,
					   &maxsize, &reverse);
	      if (!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
		  || bitsize != maxsize)
		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)))
	return 0;
      if (MEM_SIZE_KNOWN_P (decl_rtl)
	  && 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, HOST_WIDE_INT offset)
{
  tree expr2;
  HOST_WIDE_INT 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 && 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, HOST_WIDE_INT 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 (GET_MODE_SIZE (mode) > GET_MODE_SIZE (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 ((GET_MODE_SIZE (mode) > GET_MODE_SIZE (DECL_MODE (expr))
       || (store_reg_p
	   && !COMPLEX_MODE_P (DECL_MODE (expr))
	   && hard_regno_nregs[REGNO (loc)][DECL_MODE (expr)] == 1))
      && offset + byte_lowpart_offset (DECL_MODE (expr), mode) == 0)
    {
      mode = DECL_MODE (expr);
      offset = 0;
    }

  if (offset < 0 || offset >= MAX_VAR_PARTS)
    return false;

  if (mode_out)
    *mode_out = mode;
  if (offset_out)
    *offset_out = 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 offset, reg_offset, regno;

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

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

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

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

  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_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 CC0:
	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_VALUE (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_VALUE (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
	      && !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
      && hard_frame_pointer_adjustment != -1
      && preserve)
    cselib_set_value_sp_based (v);

  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));
		  machine_mode mode = TYPE_MODE (struct_addr);
		  rtx reg;
		  INIT_CUMULATIVE_ARGS (args_so_far_v, type, NULL_RTX, fndecl,
					nargs + 1);
		  reg = targetm.calls.function_arg (args_so_far, mode,
						    struct_addr, true);
		  targetm.calls.function_arg_advance (args_so_far, mode,
						      struct_addr, true);
		  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)
		{
		  machine_mode mode;
		  t = TYPE_ARG_TYPES (type);
		  mode = TYPE_MODE (TREE_VALUE (t));
		  this_arg = targetm.calls.function_arg (args_so_far, mode,
							 TREE_VALUE (t), true);
		  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);
	    if (val && cselib_preserved_value_p (val))
	      item = val->val_rtx;
	    else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT
		     || GET_MODE_CLASS (GET_MODE (x)) == MODE_PARTIAL_INT)
	      {
		machine_mode mode = GET_MODE (x);

		while ((mode = GET_MODE_WIDER_MODE (mode)) != VOIDmode
		       && GET_MODE_BITSIZE (mode) <= BITS_PER_WORD)
		  {
		    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)
	      {
		struct adjust_mem_data amd;
		amd.mem_mode = VOIDmode;
		amd.stack_adjust = -VTI (bb)->out.stack_adjust;
		amd.side_effects = NULL;
		amd.store = true;
		mem = simplify_replace_fn_rtx (mem, NULL_RTX, adjust_mems,
					       &amd);
		gcc_assert (amd.side_effects == NULL_RTX);
	      }
	    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.  */
		machine_mode imode = int_mode_for_mode (GET_MODE (mem));
		if (imode != GET_MODE (mem) && imode != BLKmode)
		  {
		    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)
	  {
	    tree argtype = TREE_VALUE (t);
	    machine_mode mode = TYPE_MODE (argtype);
	    rtx reg;
	    if (pass_by_reference (&args_so_far_v, mode, argtype, true))
	      {
		argtype = build_pointer_type (argtype);
		mode = TYPE_MODE (argtype);
	      }
	    reg = targetm.calls.function_arg (args_so_far, mode,
					      argtype, true);
	    if (TREE_CODE (argtype) == REFERENCE_TYPE
		&& INTEGRAL_TYPE_P (TREE_TYPE (argtype))
		&& reg
		&& REG_P (reg)
		&& GET_MODE (reg) == mode
		&& (GET_MODE_CLASS (mode) == MODE_INT
		    || GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
		&& REG_P (x)
		&& REGNO (x) == REGNO (reg)
		&& GET_MODE (x) == mode
		&& item)
	      {
		machine_mode indmode
		  = TYPE_MODE (TREE_TYPE (argtype));
		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, mode,
						argtype, true);
	    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 (PATTERN (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_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_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 visited, in_worklist, in_pending;
  basic_block bb;
  edge e;
  int *bb_order;
  int *rc_order;
  int i;
  int htabsz = 0;
  int htabmax = PARAM_VALUE (PARAM_MAX_VARTRACK_SIZE);
  bool success = true;

  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));
  pre_and_rev_post_order_compute (NULL, rc_order, false);
  for (i = 0; i < n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS; i++)
    bb_order[rc_order[i]] = i;
  free (rc_order);

  visited = sbitmap_alloc (last_basic_block_for_fn (cfun));
  in_worklist = sbitmap_alloc (last_basic_block_for_fn (cfun));
  in_pending = sbitmap_alloc (last_basic_block_for_fn (cfun));
  bitmap_clear (in_worklist);

  FOR_EACH_BB_FN (bb, cfun)
    pending->insert (bb_order[bb->index], bb);
  bitmap_ones (in_pending);

  while (success && !pending->empty ())
    {
      std::swap (worklist, pending);
      std::swap (in_worklist, in_pending);

      bitmap_clear (visited);

      while (!worklist->empty ())
	{
	  bb = worklist->extract_min ();
	  bitmap_clear_bit (in_worklist, bb->index);
	  gcc_assert (!bitmap_bit_p (visited, bb->index));
	  if (!bitmap_bit_p (visited, bb->index))
	    {
	      bool changed;
	      edge_iterator ei;
	      int oldinsz, oldoutsz;

	      bitmap_set_bit (visited, 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_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);
	      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_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;

		      if (bitmap_bit_p (visited, e->dest->index))
			{
			  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 (!bitmap_bit_p (in_worklist, e->dest->index))
			{
			  /* Add E->DEST to current round.  */
			  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);
		}
	    }
	}
    }

  if (success && MAY_HAVE_DEBUG_INSNS)
    FOR_EACH_BB_FN (bb, cfun)
      gcc_assert (VTI (bb)->flooded);

  free (bb_order);
  delete worklist;
  delete pending;
  sbitmap_free (visited);
  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->elements () > 0)
    {
      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.  */
struct expand_loc_callback_data
{
  /* 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)
	      + vec<loc_exp_dep, va_heap, vl_embed>::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)
{
  struct expand_loc_callback_data *elcd
    = (struct 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)
{
  struct expand_loc_callback_data *elcd
    = (struct 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)
	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)
{
  struct expand_loc_callback_data data;
  rtx result;

  if (!MAY_HAVE_DEBUG_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)
{
  struct 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;
  tree type_size_unit;
  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;

      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);
      last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);

      /* Attempt to merge adjacent registers or memory.  */
      wider_mode = GET_MODE_WIDER_MODE (mode);
      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
	  && wider_mode != VOIDmode
	  && 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;

	  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))
		   && CONST_INT_P (XEXP (XEXP (loc2, 0), 1)))
	    {
	      if ((REG_P (XEXP (loc[n_var_parts], 0))
		   && rtx_equal_p (XEXP (loc[n_var_parts], 0),
				   XEXP (XEXP (loc2, 0), 0))
		   && INTVAL (XEXP (XEXP (loc2, 0), 1))
		      == GET_MODE_SIZE (mode))
		  || (GET_CODE (XEXP (loc[n_var_parts], 0)) == PLUS
		      && CONST_INT_P (XEXP (XEXP (loc[n_var_parts], 0), 1))
		      && rtx_equal_p (XEXP (XEXP (loc[n_var_parts], 0), 0),
				      XEXP (XEXP (loc2, 0), 0))
		      && INTVAL (XEXP (XEXP (loc[n_var_parts], 0), 1))
			 + GET_MODE_SIZE (mode)
			 == INTVAL (XEXP (XEXP (loc2, 0), 1))))
		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] + GET_MODE_SIZE (mode);
	      i = j;
	    }
	}
      ++n_var_parts;
    }
  type_size_unit = TYPE_SIZE_UNIT (TREE_TYPE (decl));
  if ((unsigned HOST_WIDE_INT) last_limit < TREE_INT_CST_LOW (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))
		 || NOTE_KIND (insn) == NOTE_INSN_CALL_ARG_LOCATION))
	insn = NEXT_INSN (insn);
      if (NOTE_P (insn)
	  && ((NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION
	       && NOTE_DURING_CALL_P (insn))
	      || NOTE_KIND (insn) == NOTE_INSN_CALL_ARG_LOCATION))
	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->elements ())
    return;

  if (MAY_HAVE_DEBUG_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;
	      rtx_note *note;
	      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))
		    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);
		}
	      note = emit_note_after (NOTE_INSN_CALL_ARG_LOCATION, insn);
	      NOTE_VAR_LOCATION (note) = 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->elements ());

  /* 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_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_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_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_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, HOST_WIDE_INT *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;
	  if (REG_OFFSET (reg) < offset)
	    offset = REG_OFFSET (reg);
	}

      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;
  HOST_WIDE_INT offset;
  dataflow_set *out;
  decl_or_value dv;

  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.  */
  if (MEM_P (incoming)
      && (XEXP (incoming, 0) == crtl->args.internal_arg_pointer
	  || (GET_CODE (XEXP (incoming, 0)) == PLUS
	      && XEXP (XEXP (incoming, 0), 0)
		 == crtl->args.internal_arg_pointer
	      && CONST_INT_P (XEXP (XEXP (incoming, 0), 1)))))
    {
      HOST_WIDE_INT off = -FIRST_PARM_OFFSET (current_function_decl);
      if (GET_CODE (XEXP (incoming, 0)) == PLUS)
	off += INTVAL (XEXP (XEXP (incoming, 0), 1));
      incoming
	= replace_equiv_address_nv (incoming,
				    plus_constant (Pmode,
						   arg_pointer_rtx, off));
    }

#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))
    {
      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;
    }

  if (!track_loc_p (incoming, parm, offset, false, &mode, &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 (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, 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, offset,
			 incoming);
      set_variable_part (out, incoming, dv, 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);
		}
	    }
	}
    }
  else if (GET_CODE (incoming) == PARALLEL && !dv_onepart_p (dv))
    {
      int i;

      for (i = 0; i < XVECLEN (incoming, 0); i++)
	{
	  rtx reg = XEXP (XVECEXP (incoming, 0, i), 0);
	  offset = REG_OFFSET (reg);
	  gcc_assert (REGNO (reg) < FIRST_PSEUDO_REGISTER);
	  attrs_list_insert (&out->regs[REGNO (reg)], dv, offset, reg);
	  set_variable_part (out, reg, dv, offset,
			     VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
	}
    }
  else if (MEM_P (incoming))
    {
      incoming = var_lowpart (mode, incoming);
      set_variable_part (out, incoming, dv, 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))
    if (!POINTER_BOUNDS_P (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_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));
}

/* 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;
  HOST_WIDE_INT 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_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_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));
      expr = plus_constant (GET_MODE (stack_pointer_rtx),
			    stack_pointer_rtx, -ofst);
      cselib_add_permanent_equiv (val, expr, get_insns ());

      if (ofst)
	{
	  val = cselib_lookup_from_insn (stack_pointer_rtx,
					 GET_MODE (stack_pointer_rtx), 1,
					 VOIDmode, get_insns ());
	  preserve_value (val);
	  expr = plus_constant (GET_MODE (reg), reg, 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 -= INTVAL (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 ();

  FOR_EACH_BB_FN (bb, cfun)
    {
      rtx_insn *insn;
      HOST_WIDE_INT pre, post = 0;
      basic_block first_bb, last_bb;

      if (MAY_HAVE_DEBUG_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 ());
	}

      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;
	  for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
	       insn = NEXT_INSN (insn))
	    {
	      if (INSN_P (insn))
		{
		  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);
			  VTI (bb)->out.stack_adjust += pre;
			}
		    }

		  cselib_hook_called = false;
		  adjust_insn (bb, insn);
		  if (MAY_HAVE_DEBUG_INSNS)
		    {
		      if (CALL_P (insn))
			prepare_call_arguments (bb, insn);
		      cselib_process_insn (insn);
		      if (dump_file && (dump_flags & TDF_DETAILS))
			{
			  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 (!frame_pointer_needed && 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 (fp_cfa_offset != -1
		      && 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_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_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;

/* Get rid of all debug insns from the insn stream.  */

static void
delete_debug_insns (void)
{
  basic_block bb;
  rtx_insn *insn, *next;

  if (!MAY_HAVE_DEBUG_INSNS)
    return;

  FOR_EACH_BB_FN (bb, cfun)
    {
      FOR_BB_INSNS_SAFE (bb, insn, next)
	if (DEBUG_INSN_P (insn))
	  {
	    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);
	  }
    }
}

/* 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_debug_insns ();
}

/* 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_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;

  if (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_debug_insns ();
      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;
    }

  mark_dfs_back_edges ();
  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_debug_insns ();

      /* 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: */
  virtual bool gate (function *)
    {
      return (flag_var_tracking && !targetm.delay_vartrack);
    }

  virtual unsigned int execute (function *)
    {
      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);
}
