/* SCC value numbering for trees
   Copyright (C) 2006-2020 Free Software Foundation, Inc.
   Contributed by Daniel Berlin <dan@dberlin.org>

This file is part of GCC.

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

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

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

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "splay-tree.h"
#include "backend.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "ssa.h"
#include "expmed.h"
#include "insn-config.h"
#include "memmodel.h"
#include "emit-rtl.h"
#include "cgraph.h"
#include "gimple-pretty-print.h"
#include "alias.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "cfganal.h"
#include "tree-inline.h"
#include "internal-fn.h"
#include "gimple-fold.h"
#include "tree-eh.h"
#include "gimplify.h"
#include "flags.h"
#include "dojump.h"
#include "explow.h"
#include "calls.h"
#include "varasm.h"
#include "stmt.h"
#include "expr.h"
#include "tree-dfa.h"
#include "tree-ssa.h"
#include "dumpfile.h"
#include "cfgloop.h"
#include "tree-ssa-propagate.h"
#include "tree-cfg.h"
#include "domwalk.h"
#include "gimple-iterator.h"
#include "gimple-match.h"
#include "stringpool.h"
#include "attribs.h"
#include "tree-pass.h"
#include "statistics.h"
#include "langhooks.h"
#include "ipa-utils.h"
#include "dbgcnt.h"
#include "tree-cfgcleanup.h"
#include "tree-ssa-loop.h"
#include "tree-scalar-evolution.h"
#include "tree-ssa-loop-niter.h"
#include "builtins.h"
#include "tree-ssa-sccvn.h"

/* This algorithm is based on the SCC algorithm presented by Keith
   Cooper and L. Taylor Simpson in "SCC-Based Value numbering"
   (http://citeseer.ist.psu.edu/41805.html).  In
   straight line code, it is equivalent to a regular hash based value
   numbering that is performed in reverse postorder.

   For code with cycles, there are two alternatives, both of which
   require keeping the hashtables separate from the actual list of
   value numbers for SSA names.

   1. Iterate value numbering in an RPO walk of the blocks, removing
   all the entries from the hashtable after each iteration (but
   keeping the SSA name->value number mapping between iterations).
   Iterate until it does not change.

   2. Perform value numbering as part of an SCC walk on the SSA graph,
   iterating only the cycles in the SSA graph until they do not change
   (using a separate, optimistic hashtable for value numbering the SCC
   operands).

   The second is not just faster in practice (because most SSA graph
   cycles do not involve all the variables in the graph), it also has
   some nice properties.

   One of these nice properties is that when we pop an SCC off the
   stack, we are guaranteed to have processed all the operands coming from
   *outside of that SCC*, so we do not need to do anything special to
   ensure they have value numbers.

   Another nice property is that the SCC walk is done as part of a DFS
   of the SSA graph, which makes it easy to perform combining and
   simplifying operations at the same time.

   The code below is deliberately written in a way that makes it easy
   to separate the SCC walk from the other work it does.

   In order to propagate constants through the code, we track which
   expressions contain constants, and use those while folding.  In
   theory, we could also track expressions whose value numbers are
   replaced, in case we end up folding based on expression
   identities.

   In order to value number memory, we assign value numbers to vuses.
   This enables us to note that, for example, stores to the same
   address of the same value from the same starting memory states are
   equivalent.
   TODO:

   1. We can iterate only the changing portions of the SCC's, but
   I have not seen an SCC big enough for this to be a win.
   2. If you differentiate between phi nodes for loops and phi nodes
   for if-then-else, you can properly consider phi nodes in different
   blocks for equivalence.
   3. We could value number vuses in more cases, particularly, whole
   structure copies.
*/

/* There's no BB_EXECUTABLE but we can use BB_VISITED.  */
#define BB_EXECUTABLE BB_VISITED

static vn_lookup_kind default_vn_walk_kind;

/* vn_nary_op hashtable helpers.  */

struct vn_nary_op_hasher : nofree_ptr_hash <vn_nary_op_s>
{
  typedef vn_nary_op_s *compare_type;
  static inline hashval_t hash (const vn_nary_op_s *);
  static inline bool equal (const vn_nary_op_s *, const vn_nary_op_s *);
};

/* Return the computed hashcode for nary operation P1.  */

inline hashval_t
vn_nary_op_hasher::hash (const vn_nary_op_s *vno1)
{
  return vno1->hashcode;
}

/* Compare nary operations P1 and P2 and return true if they are
   equivalent.  */

inline bool
vn_nary_op_hasher::equal (const vn_nary_op_s *vno1, const vn_nary_op_s *vno2)
{
  return vno1 == vno2 || vn_nary_op_eq (vno1, vno2);
}

typedef hash_table<vn_nary_op_hasher> vn_nary_op_table_type;
typedef vn_nary_op_table_type::iterator vn_nary_op_iterator_type;


/* vn_phi hashtable helpers.  */

static int
vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2);

struct vn_phi_hasher : nofree_ptr_hash <vn_phi_s>
{ 
  static inline hashval_t hash (const vn_phi_s *);
  static inline bool equal (const vn_phi_s *, const vn_phi_s *);
};

/* Return the computed hashcode for phi operation P1.  */

inline hashval_t
vn_phi_hasher::hash (const vn_phi_s *vp1)
{
  return vp1->hashcode;
}

/* Compare two phi entries for equality, ignoring VN_TOP arguments.  */

inline bool
vn_phi_hasher::equal (const vn_phi_s *vp1, const vn_phi_s *vp2)
{
  return vp1 == vp2 || vn_phi_eq (vp1, vp2);
}

typedef hash_table<vn_phi_hasher> vn_phi_table_type;
typedef vn_phi_table_type::iterator vn_phi_iterator_type;


/* Compare two reference operands P1 and P2 for equality.  Return true if
   they are equal, and false otherwise.  */

static int
vn_reference_op_eq (const void *p1, const void *p2)
{
  const_vn_reference_op_t const vro1 = (const_vn_reference_op_t) p1;
  const_vn_reference_op_t const vro2 = (const_vn_reference_op_t) p2;

  return (vro1->opcode == vro2->opcode
	  /* We do not care for differences in type qualification.  */
	  && (vro1->type == vro2->type
	      || (vro1->type && vro2->type
		  && types_compatible_p (TYPE_MAIN_VARIANT (vro1->type),
					 TYPE_MAIN_VARIANT (vro2->type))))
	  && expressions_equal_p (vro1->op0, vro2->op0)
	  && expressions_equal_p (vro1->op1, vro2->op1)
	  && expressions_equal_p (vro1->op2, vro2->op2));
}

/* Free a reference operation structure VP.  */

static inline void
free_reference (vn_reference_s *vr)
{
  vr->operands.release ();
}


/* vn_reference hashtable helpers.  */

struct vn_reference_hasher : nofree_ptr_hash <vn_reference_s>
{
  static inline hashval_t hash (const vn_reference_s *);
  static inline bool equal (const vn_reference_s *, const vn_reference_s *);
};

/* Return the hashcode for a given reference operation P1.  */

inline hashval_t
vn_reference_hasher::hash (const vn_reference_s *vr1)
{
  return vr1->hashcode;
}

inline bool
vn_reference_hasher::equal (const vn_reference_s *v, const vn_reference_s *c)
{
  return v == c || vn_reference_eq (v, c);
}

typedef hash_table<vn_reference_hasher> vn_reference_table_type;
typedef vn_reference_table_type::iterator vn_reference_iterator_type;


/* The set of VN hashtables.  */

typedef struct vn_tables_s
{
  vn_nary_op_table_type *nary;
  vn_phi_table_type *phis;
  vn_reference_table_type *references;
} *vn_tables_t;


/* vn_constant hashtable helpers.  */

struct vn_constant_hasher : free_ptr_hash <vn_constant_s>
{ 
  static inline hashval_t hash (const vn_constant_s *);
  static inline bool equal (const vn_constant_s *, const vn_constant_s *);
};

/* Hash table hash function for vn_constant_t.  */

inline hashval_t
vn_constant_hasher::hash (const vn_constant_s *vc1)
{
  return vc1->hashcode;
}

/* Hash table equality function for vn_constant_t.  */

inline bool
vn_constant_hasher::equal (const vn_constant_s *vc1, const vn_constant_s *vc2)
{
  if (vc1->hashcode != vc2->hashcode)
    return false;

  return vn_constant_eq_with_type (vc1->constant, vc2->constant);
}

static hash_table<vn_constant_hasher> *constant_to_value_id;
static bitmap constant_value_ids;


/* Obstack we allocate the vn-tables elements from.  */
static obstack vn_tables_obstack;
/* Special obstack we never unwind.  */
static obstack vn_tables_insert_obstack;

static vn_reference_t last_inserted_ref;
static vn_phi_t last_inserted_phi;
static vn_nary_op_t last_inserted_nary;

/* Valid hashtables storing information we have proven to be
   correct.  */
static vn_tables_t valid_info;


/* Valueization hook.  Valueize NAME if it is an SSA name, otherwise
   just return it.  */
tree (*vn_valueize) (tree);
tree vn_valueize_wrapper (tree t, void* context ATTRIBUTE_UNUSED)
{
  return vn_valueize (t);
}


/* This represents the top of the VN lattice, which is the universal
   value.  */

tree VN_TOP;

/* Unique counter for our value ids.  */

static unsigned int next_value_id;


/* Table of vn_ssa_aux_t's, one per ssa_name.  The vn_ssa_aux_t objects
   are allocated on an obstack for locality reasons, and to free them
   without looping over the vec.  */

struct vn_ssa_aux_hasher : typed_noop_remove <vn_ssa_aux_t>
{
  typedef vn_ssa_aux_t value_type;
  typedef tree compare_type;
  static inline hashval_t hash (const value_type &);
  static inline bool equal (const value_type &, const compare_type &);
  static inline void mark_deleted (value_type &) {}
  static const bool empty_zero_p = true;
  static inline void mark_empty (value_type &e) { e = NULL; }
  static inline bool is_deleted (value_type &) { return false; }
  static inline bool is_empty (value_type &e) { return e == NULL; }
};

hashval_t
vn_ssa_aux_hasher::hash (const value_type &entry)
{
  return SSA_NAME_VERSION (entry->name);
}

bool
vn_ssa_aux_hasher::equal (const value_type &entry, const compare_type &name)
{
  return name == entry->name;
}

static hash_table<vn_ssa_aux_hasher> *vn_ssa_aux_hash;
typedef hash_table<vn_ssa_aux_hasher>::iterator vn_ssa_aux_iterator_type;
static struct obstack vn_ssa_aux_obstack;

static vn_nary_op_t vn_nary_op_insert_stmt (gimple *, tree);
static unsigned int vn_nary_length_from_stmt (gimple *);
static vn_nary_op_t alloc_vn_nary_op_noinit (unsigned int, obstack *);
static vn_nary_op_t vn_nary_op_insert_into (vn_nary_op_t,
					    vn_nary_op_table_type *, bool);
static void init_vn_nary_op_from_stmt (vn_nary_op_t, gimple *);
static void init_vn_nary_op_from_pieces (vn_nary_op_t, unsigned int,
					 enum tree_code, tree, tree *);
static tree vn_lookup_simplify_result (gimple_match_op *);
static vn_reference_t vn_reference_lookup_or_insert_for_pieces
	  (tree, alias_set_type, alias_set_type, tree,
	   vec<vn_reference_op_s, va_heap>, tree);

/* Return whether there is value numbering information for a given SSA name.  */

bool
has_VN_INFO (tree name)
{
  return vn_ssa_aux_hash->find_with_hash (name, SSA_NAME_VERSION (name));
}

vn_ssa_aux_t
VN_INFO (tree name)
{
  vn_ssa_aux_t *res
    = vn_ssa_aux_hash->find_slot_with_hash (name, SSA_NAME_VERSION (name),
					    INSERT);
  if (*res != NULL)
    return *res;

  vn_ssa_aux_t newinfo = *res = XOBNEW (&vn_ssa_aux_obstack, struct vn_ssa_aux);
  memset (newinfo, 0, sizeof (struct vn_ssa_aux));
  newinfo->name = name;
  newinfo->valnum = VN_TOP;
  /* We are using the visited flag to handle uses with defs not within the
     region being value-numbered.  */
  newinfo->visited = false;

  /* Given we create the VN_INFOs on-demand now we have to do initialization
     different than VN_TOP here.  */
  if (SSA_NAME_IS_DEFAULT_DEF (name))
    switch (TREE_CODE (SSA_NAME_VAR (name)))
      {
      case VAR_DECL:
        /* All undefined vars are VARYING.  */
        newinfo->valnum = name;
	newinfo->visited = true;
	break;

      case PARM_DECL:
	/* Parameters are VARYING but we can record a condition
	   if we know it is a non-NULL pointer.  */
	newinfo->visited = true;
	newinfo->valnum = name;
	if (POINTER_TYPE_P (TREE_TYPE (name))
	    && nonnull_arg_p (SSA_NAME_VAR (name)))
	  {
	    tree ops[2];
	    ops[0] = name;
	    ops[1] = build_int_cst (TREE_TYPE (name), 0);
	    vn_nary_op_t nary;
	    /* Allocate from non-unwinding stack.  */
	    nary = alloc_vn_nary_op_noinit (2, &vn_tables_insert_obstack);
	    init_vn_nary_op_from_pieces (nary, 2, NE_EXPR,
					 boolean_type_node, ops);
	    nary->predicated_values = 0;
	    nary->u.result = boolean_true_node;
	    vn_nary_op_insert_into (nary, valid_info->nary, true);
	    gcc_assert (nary->unwind_to == NULL);
	    /* Also do not link it into the undo chain.  */
	    last_inserted_nary = nary->next;
	    nary->next = (vn_nary_op_t)(void *)-1;
	    nary = alloc_vn_nary_op_noinit (2, &vn_tables_insert_obstack);
	    init_vn_nary_op_from_pieces (nary, 2, EQ_EXPR,
					 boolean_type_node, ops);
	    nary->predicated_values = 0;
	    nary->u.result = boolean_false_node;
	    vn_nary_op_insert_into (nary, valid_info->nary, true);
	    gcc_assert (nary->unwind_to == NULL);
	    last_inserted_nary = nary->next;
	    nary->next = (vn_nary_op_t)(void *)-1;
	    if (dump_file && (dump_flags & TDF_DETAILS))
	      {
		fprintf (dump_file, "Recording ");
		print_generic_expr (dump_file, name, TDF_SLIM);
		fprintf (dump_file, " != 0\n");
	      }
	  }
	break;

      case RESULT_DECL:
	/* If the result is passed by invisible reference the default
	   def is initialized, otherwise it's uninitialized.  Still
	   undefined is varying.  */
	newinfo->visited = true;
	newinfo->valnum = name;
	break;

      default:
	gcc_unreachable ();
      }
  return newinfo;
}

/* Return the SSA value of X.  */

inline tree
SSA_VAL (tree x, bool *visited = NULL)
{
  vn_ssa_aux_t tem = vn_ssa_aux_hash->find_with_hash (x, SSA_NAME_VERSION (x));
  if (visited)
    *visited = tem && tem->visited;
  return tem && tem->visited ? tem->valnum : x;
}

/* Return the SSA value of the VUSE x, supporting released VDEFs
   during elimination which will value-number the VDEF to the
   associated VUSE (but not substitute in the whole lattice).  */

static inline tree
vuse_ssa_val (tree x)
{
  if (!x)
    return NULL_TREE;

  do
    {
      x = SSA_VAL (x);
      gcc_assert (x != VN_TOP);
    }
  while (SSA_NAME_IN_FREE_LIST (x));

  return x;
}

/* Similar to the above but used as callback for walk_non_aliases_vuses
   and thus should stop at unvisited VUSE to not walk across region
   boundaries.  */

static tree
vuse_valueize (tree vuse)
{
  do
    {
      bool visited;
      vuse = SSA_VAL (vuse, &visited);
      if (!visited)
	return NULL_TREE;
      gcc_assert (vuse != VN_TOP);
    }
  while (SSA_NAME_IN_FREE_LIST (vuse));
  return vuse;
}


/* Return the vn_kind the expression computed by the stmt should be
   associated with.  */

enum vn_kind
vn_get_stmt_kind (gimple *stmt)
{
  switch (gimple_code (stmt))
    {
    case GIMPLE_CALL:
      return VN_REFERENCE;
    case GIMPLE_PHI:
      return VN_PHI;
    case GIMPLE_ASSIGN:
      {
	enum tree_code code = gimple_assign_rhs_code (stmt);
	tree rhs1 = gimple_assign_rhs1 (stmt);
	switch (get_gimple_rhs_class (code))
	  {
	  case GIMPLE_UNARY_RHS:
	  case GIMPLE_BINARY_RHS:
	  case GIMPLE_TERNARY_RHS:
	    return VN_NARY;
	  case GIMPLE_SINGLE_RHS:
	    switch (TREE_CODE_CLASS (code))
	      {
	      case tcc_reference:
		/* VOP-less references can go through unary case.  */
		if ((code == REALPART_EXPR
		     || code == IMAGPART_EXPR
		     || code == VIEW_CONVERT_EXPR
		     || code == BIT_FIELD_REF)
		    && TREE_CODE (TREE_OPERAND (rhs1, 0)) == SSA_NAME)
		  return VN_NARY;

		/* Fallthrough.  */
	      case tcc_declaration:
		return VN_REFERENCE;

	      case tcc_constant:
		return VN_CONSTANT;

	      default:
		if (code == ADDR_EXPR)
		  return (is_gimple_min_invariant (rhs1)
			  ? VN_CONSTANT : VN_REFERENCE);
		else if (code == CONSTRUCTOR)
		  return VN_NARY;
		return VN_NONE;
	      }
	  default:
	    return VN_NONE;
	  }
      }
    default:
      return VN_NONE;
    }
}

/* Lookup a value id for CONSTANT and return it.  If it does not
   exist returns 0.  */

unsigned int
get_constant_value_id (tree constant)
{
  vn_constant_s **slot;
  struct vn_constant_s vc;

  vc.hashcode = vn_hash_constant_with_type (constant);
  vc.constant = constant;
  slot = constant_to_value_id->find_slot (&vc, NO_INSERT);
  if (slot)
    return (*slot)->value_id;
  return 0;
}

/* Lookup a value id for CONSTANT, and if it does not exist, create a
   new one and return it.  If it does exist, return it.  */

unsigned int
get_or_alloc_constant_value_id (tree constant)
{
  vn_constant_s **slot;
  struct vn_constant_s vc;
  vn_constant_t vcp;

  /* If the hashtable isn't initialized we're not running from PRE and thus
     do not need value-ids.  */
  if (!constant_to_value_id)
    return 0;

  vc.hashcode = vn_hash_constant_with_type (constant);
  vc.constant = constant;
  slot = constant_to_value_id->find_slot (&vc, INSERT);
  if (*slot)
    return (*slot)->value_id;

  vcp = XNEW (struct vn_constant_s);
  vcp->hashcode = vc.hashcode;
  vcp->constant = constant;
  vcp->value_id = get_next_value_id ();
  *slot = vcp;
  bitmap_set_bit (constant_value_ids, vcp->value_id);
  return vcp->value_id;
}

/* Return true if V is a value id for a constant.  */

bool
value_id_constant_p (unsigned int v)
{
  return bitmap_bit_p (constant_value_ids, v);
}

/* Compute the hash for a reference operand VRO1.  */

static void
vn_reference_op_compute_hash (const vn_reference_op_t vro1, inchash::hash &hstate)
{
  hstate.add_int (vro1->opcode);
  if (vro1->op0)
    inchash::add_expr (vro1->op0, hstate);
  if (vro1->op1)
    inchash::add_expr (vro1->op1, hstate);
  if (vro1->op2)
    inchash::add_expr (vro1->op2, hstate);
}

/* Compute a hash for the reference operation VR1 and return it.  */

static hashval_t
vn_reference_compute_hash (const vn_reference_t vr1)
{
  inchash::hash hstate;
  hashval_t result;
  int i;
  vn_reference_op_t vro;
  poly_int64 off = -1;
  bool deref = false;

  FOR_EACH_VEC_ELT (vr1->operands, i, vro)
    {
      if (vro->opcode == MEM_REF)
	deref = true;
      else if (vro->opcode != ADDR_EXPR)
	deref = false;
      if (maybe_ne (vro->off, -1))
	{
	  if (known_eq (off, -1))
	    off = 0;
	  off += vro->off;
	}
      else
	{
	  if (maybe_ne (off, -1)
	      && maybe_ne (off, 0))
	    hstate.add_poly_int (off);
	  off = -1;
	  if (deref
	      && vro->opcode == ADDR_EXPR)
	    {
	      if (vro->op0)
		{
		  tree op = TREE_OPERAND (vro->op0, 0);
		  hstate.add_int (TREE_CODE (op));
		  inchash::add_expr (op, hstate);
		}
	    }
	  else
	    vn_reference_op_compute_hash (vro, hstate);
	}
    }
  result = hstate.end ();
  /* ??? We would ICE later if we hash instead of adding that in. */
  if (vr1->vuse)
    result += SSA_NAME_VERSION (vr1->vuse);

  return result;
}

/* Return true if reference operations VR1 and VR2 are equivalent.  This
   means they have the same set of operands and vuses.  */

bool
vn_reference_eq (const_vn_reference_t const vr1, const_vn_reference_t const vr2)
{
  unsigned i, j;

  /* Early out if this is not a hash collision.  */
  if (vr1->hashcode != vr2->hashcode)
    return false;

  /* The VOP needs to be the same.  */
  if (vr1->vuse != vr2->vuse)
    return false;

  /* If the operands are the same we are done.  */
  if (vr1->operands == vr2->operands)
    return true;

  if (!expressions_equal_p (TYPE_SIZE (vr1->type), TYPE_SIZE (vr2->type)))
    return false;

  if (INTEGRAL_TYPE_P (vr1->type)
      && INTEGRAL_TYPE_P (vr2->type))
    {
      if (TYPE_PRECISION (vr1->type) != TYPE_PRECISION (vr2->type))
	return false;
    }
  else if (INTEGRAL_TYPE_P (vr1->type)
	   && (TYPE_PRECISION (vr1->type)
	       != TREE_INT_CST_LOW (TYPE_SIZE (vr1->type))))
    return false;
  else if (INTEGRAL_TYPE_P (vr2->type)
	   && (TYPE_PRECISION (vr2->type)
	       != TREE_INT_CST_LOW (TYPE_SIZE (vr2->type))))
    return false;

  i = 0;
  j = 0;
  do
    {
      poly_int64 off1 = 0, off2 = 0;
      vn_reference_op_t vro1, vro2;
      vn_reference_op_s tem1, tem2;
      bool deref1 = false, deref2 = false;
      for (; vr1->operands.iterate (i, &vro1); i++)
	{
	  if (vro1->opcode == MEM_REF)
	    deref1 = true;
	  /* Do not look through a storage order barrier.  */
	  else if (vro1->opcode == VIEW_CONVERT_EXPR && vro1->reverse)
	    return false;
	  if (known_eq (vro1->off, -1))
	    break;
	  off1 += vro1->off;
	}
      for (; vr2->operands.iterate (j, &vro2); j++)
	{
	  if (vro2->opcode == MEM_REF)
	    deref2 = true;
	  /* Do not look through a storage order barrier.  */
	  else if (vro2->opcode == VIEW_CONVERT_EXPR && vro2->reverse)
	    return false;
	  if (known_eq (vro2->off, -1))
	    break;
	  off2 += vro2->off;
	}
      if (maybe_ne (off1, off2))
	return false;
      if (deref1 && vro1->opcode == ADDR_EXPR)
	{
	  memset (&tem1, 0, sizeof (tem1));
	  tem1.op0 = TREE_OPERAND (vro1->op0, 0);
	  tem1.type = TREE_TYPE (tem1.op0);
	  tem1.opcode = TREE_CODE (tem1.op0);
	  vro1 = &tem1;
	  deref1 = false;
	}
      if (deref2 && vro2->opcode == ADDR_EXPR)
	{
	  memset (&tem2, 0, sizeof (tem2));
	  tem2.op0 = TREE_OPERAND (vro2->op0, 0);
	  tem2.type = TREE_TYPE (tem2.op0);
	  tem2.opcode = TREE_CODE (tem2.op0);
	  vro2 = &tem2;
	  deref2 = false;
	}
      if (deref1 != deref2)
	return false;
      if (!vn_reference_op_eq (vro1, vro2))
	return false;
      ++j;
      ++i;
    }
  while (vr1->operands.length () != i
	 || vr2->operands.length () != j);

  return true;
}

/* Copy the operations present in load/store REF into RESULT, a vector of
   vn_reference_op_s's.  */

static void
copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result)
{
  /* For non-calls, store the information that makes up the address.  */
  tree orig = ref;
  while (ref)
    {
      vn_reference_op_s temp;

      memset (&temp, 0, sizeof (temp));
      temp.type = TREE_TYPE (ref);
      temp.opcode = TREE_CODE (ref);
      temp.off = -1;

      switch (temp.opcode)
	{
	case MODIFY_EXPR:
	  temp.op0 = TREE_OPERAND (ref, 1);
	  break;
	case WITH_SIZE_EXPR:
	  temp.op0 = TREE_OPERAND (ref, 1);
	  temp.off = 0;
	  break;
	case MEM_REF:
	  /* The base address gets its own vn_reference_op_s structure.  */
	  temp.op0 = TREE_OPERAND (ref, 1);
	  if (!mem_ref_offset (ref).to_shwi (&temp.off))
	    temp.off = -1;
	  temp.clique = MR_DEPENDENCE_CLIQUE (ref);
	  temp.base = MR_DEPENDENCE_BASE (ref);
	  temp.reverse = REF_REVERSE_STORAGE_ORDER (ref);
	  break;
	case TARGET_MEM_REF:
	  /* The base address gets its own vn_reference_op_s structure.  */
	  temp.op0 = TMR_INDEX (ref);
	  temp.op1 = TMR_STEP (ref);
	  temp.op2 = TMR_OFFSET (ref);
	  temp.clique = MR_DEPENDENCE_CLIQUE (ref);
	  temp.base = MR_DEPENDENCE_BASE (ref);
	  result->safe_push (temp);
	  memset (&temp, 0, sizeof (temp));
	  temp.type = NULL_TREE;
	  temp.opcode = ERROR_MARK;
	  temp.op0 = TMR_INDEX2 (ref);
	  temp.off = -1;
	  break;
	case BIT_FIELD_REF:
	  /* Record bits, position and storage order.  */
	  temp.op0 = TREE_OPERAND (ref, 1);
	  temp.op1 = TREE_OPERAND (ref, 2);
	  if (!multiple_p (bit_field_offset (ref), BITS_PER_UNIT, &temp.off))
	    temp.off = -1;
	  temp.reverse = REF_REVERSE_STORAGE_ORDER (ref);
	  break;
	case COMPONENT_REF:
	  /* The field decl is enough to unambiguously specify the field,
	     a matching type is not necessary and a mismatching type
	     is always a spurious difference.  */
	  temp.type = NULL_TREE;
	  temp.op0 = TREE_OPERAND (ref, 1);
	  temp.op1 = TREE_OPERAND (ref, 2);
	  {
	    tree this_offset = component_ref_field_offset (ref);
	    if (this_offset
		&& poly_int_tree_p (this_offset))
	      {
		tree bit_offset = DECL_FIELD_BIT_OFFSET (TREE_OPERAND (ref, 1));
		if (TREE_INT_CST_LOW (bit_offset) % BITS_PER_UNIT == 0)
		  {
		    poly_offset_int off
		      = (wi::to_poly_offset (this_offset)
			 + (wi::to_offset (bit_offset) >> LOG2_BITS_PER_UNIT));
		    /* Probibit value-numbering zero offset components
		       of addresses the same before the pass folding
		       __builtin_object_size had a chance to run
		       (checking cfun->after_inlining does the
		       trick here).  */
		    if (TREE_CODE (orig) != ADDR_EXPR
			|| maybe_ne (off, 0)
			|| cfun->after_inlining)
		      off.to_shwi (&temp.off);
		  }
	      }
	  }
	  break;
	case ARRAY_RANGE_REF:
	case ARRAY_REF:
	  {
	    tree eltype = TREE_TYPE (TREE_TYPE (TREE_OPERAND (ref, 0)));
	    /* Record index as operand.  */
	    temp.op0 = TREE_OPERAND (ref, 1);
	    /* Always record lower bounds and element size.  */
	    temp.op1 = array_ref_low_bound (ref);
	    /* But record element size in units of the type alignment.  */
	    temp.op2 = TREE_OPERAND (ref, 3);
	    temp.align = eltype->type_common.align;
	    if (! temp.op2)
	      temp.op2 = size_binop (EXACT_DIV_EXPR, TYPE_SIZE_UNIT (eltype),
				     size_int (TYPE_ALIGN_UNIT (eltype)));
	    if (poly_int_tree_p (temp.op0)
		&& poly_int_tree_p (temp.op1)
		&& TREE_CODE (temp.op2) == INTEGER_CST)
	      {
		poly_offset_int off = ((wi::to_poly_offset (temp.op0)
					- wi::to_poly_offset (temp.op1))
				       * wi::to_offset (temp.op2)
				       * vn_ref_op_align_unit (&temp));
		off.to_shwi (&temp.off);
	      }
	  }
	  break;
	case VAR_DECL:
	  if (DECL_HARD_REGISTER (ref))
	    {
	      temp.op0 = ref;
	      break;
	    }
	  /* Fallthru.  */
	case PARM_DECL:
	case CONST_DECL:
	case RESULT_DECL:
	  /* Canonicalize decls to MEM[&decl] which is what we end up with
	     when valueizing MEM[ptr] with ptr = &decl.  */
	  temp.opcode = MEM_REF;
	  temp.op0 = build_int_cst (build_pointer_type (TREE_TYPE (ref)), 0);
	  temp.off = 0;
	  result->safe_push (temp);
	  temp.opcode = ADDR_EXPR;
	  temp.op0 = build1 (ADDR_EXPR, TREE_TYPE (temp.op0), ref);
	  temp.type = TREE_TYPE (temp.op0);
	  temp.off = -1;
	  break;
	case STRING_CST:
	case INTEGER_CST:
	case POLY_INT_CST:
	case COMPLEX_CST:
	case VECTOR_CST:
	case REAL_CST:
	case FIXED_CST:
	case CONSTRUCTOR:
	case SSA_NAME:
	  temp.op0 = ref;
	  break;
	case ADDR_EXPR:
	  if (is_gimple_min_invariant (ref))
	    {
	      temp.op0 = ref;
	      break;
	    }
	  break;
	  /* These are only interesting for their operands, their
	     existence, and their type.  They will never be the last
	     ref in the chain of references (IE they require an
	     operand), so we don't have to put anything
	     for op* as it will be handled by the iteration  */
	case REALPART_EXPR:
	  temp.off = 0;
	  break;
	case VIEW_CONVERT_EXPR:
	  temp.off = 0;
	  temp.reverse = storage_order_barrier_p (ref);
	  break;
	case IMAGPART_EXPR:
	  /* This is only interesting for its constant offset.  */
	  temp.off = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (ref)));
	  break;
	default:
	  gcc_unreachable ();
	}
      result->safe_push (temp);

      if (REFERENCE_CLASS_P (ref)
	  || TREE_CODE (ref) == MODIFY_EXPR
	  || TREE_CODE (ref) == WITH_SIZE_EXPR
	  || (TREE_CODE (ref) == ADDR_EXPR
	      && !is_gimple_min_invariant (ref)))
	ref = TREE_OPERAND (ref, 0);
      else
	ref = NULL_TREE;
    }
}

/* Build a alias-oracle reference abstraction in *REF from the vn_reference
   operands in *OPS, the reference alias set SET and the reference type TYPE.
   Return true if something useful was produced.  */

bool
ao_ref_init_from_vn_reference (ao_ref *ref,
			       alias_set_type set, alias_set_type base_set,
			       tree type, vec<vn_reference_op_s> ops)
{
  vn_reference_op_t op;
  unsigned i;
  tree base = NULL_TREE;
  tree *op0_p = &base;
  poly_offset_int offset = 0;
  poly_offset_int max_size;
  poly_offset_int size = -1;
  tree size_tree = NULL_TREE;

  /* First get the final access size from just the outermost expression.  */
  op = &ops[0];
  if (op->opcode == COMPONENT_REF)
    size_tree = DECL_SIZE (op->op0);
  else if (op->opcode == BIT_FIELD_REF)
    size_tree = op->op0;
  else
    {
      machine_mode mode = TYPE_MODE (type);
      if (mode == BLKmode)
	size_tree = TYPE_SIZE (type);
      else
	size = GET_MODE_BITSIZE (mode);
    }
  if (size_tree != NULL_TREE
      && poly_int_tree_p (size_tree))
    size = wi::to_poly_offset (size_tree);

  /* Initially, maxsize is the same as the accessed element size.
     In the following it will only grow (or become -1).  */
  max_size = size;

  /* Compute cumulative bit-offset for nested component-refs and array-refs,
     and find the ultimate containing object.  */
  FOR_EACH_VEC_ELT (ops, i, op)
    {
      switch (op->opcode)
	{
	/* These may be in the reference ops, but we cannot do anything
	   sensible with them here.  */
	case ADDR_EXPR:
	  /* Apart from ADDR_EXPR arguments to MEM_REF.  */
	  if (base != NULL_TREE
	      && TREE_CODE (base) == MEM_REF
	      && op->op0
	      && DECL_P (TREE_OPERAND (op->op0, 0)))
	    {
	      vn_reference_op_t pop = &ops[i-1];
	      base = TREE_OPERAND (op->op0, 0);
	      if (known_eq (pop->off, -1))
		{
		  max_size = -1;
		  offset = 0;
		}
	      else
		offset += pop->off * BITS_PER_UNIT;
	      op0_p = NULL;
	      break;
	    }
	  /* Fallthru.  */
	case CALL_EXPR:
	  return false;

	/* Record the base objects.  */
	case MEM_REF:
	  *op0_p = build2 (MEM_REF, op->type,
			   NULL_TREE, op->op0);
	  MR_DEPENDENCE_CLIQUE (*op0_p) = op->clique;
	  MR_DEPENDENCE_BASE (*op0_p) = op->base;
	  op0_p = &TREE_OPERAND (*op0_p, 0);
	  break;

	case VAR_DECL:
	case PARM_DECL:
	case RESULT_DECL:
	case SSA_NAME:
	  *op0_p = op->op0;
	  op0_p = NULL;
	  break;

	/* And now the usual component-reference style ops.  */
	case BIT_FIELD_REF:
	  offset += wi::to_poly_offset (op->op1);
	  break;

	case COMPONENT_REF:
	  {
	    tree field = op->op0;
	    /* We do not have a complete COMPONENT_REF tree here so we
	       cannot use component_ref_field_offset.  Do the interesting
	       parts manually.  */
	    tree this_offset = DECL_FIELD_OFFSET (field);

	    if (op->op1 || !poly_int_tree_p (this_offset))
	      max_size = -1;
	    else
	      {
		poly_offset_int woffset = (wi::to_poly_offset (this_offset)
					   << LOG2_BITS_PER_UNIT);
		woffset += wi::to_offset (DECL_FIELD_BIT_OFFSET (field));
		offset += woffset;
	      }
	    break;
	  }

	case ARRAY_RANGE_REF:
	case ARRAY_REF:
	  /* We recorded the lower bound and the element size.  */
	  if (!poly_int_tree_p (op->op0)
	      || !poly_int_tree_p (op->op1)
	      || TREE_CODE (op->op2) != INTEGER_CST)
	    max_size = -1;
	  else
	    {
	      poly_offset_int woffset
		= wi::sext (wi::to_poly_offset (op->op0)
			    - wi::to_poly_offset (op->op1),
			    TYPE_PRECISION (TREE_TYPE (op->op0)));
	      woffset *= wi::to_offset (op->op2) * vn_ref_op_align_unit (op);
	      woffset <<= LOG2_BITS_PER_UNIT;
	      offset += woffset;
	    }
	  break;

	case REALPART_EXPR:
	  break;

	case IMAGPART_EXPR:
	  offset += size;
	  break;

	case VIEW_CONVERT_EXPR:
	  break;

	case STRING_CST:
	case INTEGER_CST:
	case COMPLEX_CST:
	case VECTOR_CST:
	case REAL_CST:
	case CONSTRUCTOR:
	case CONST_DECL:
	  return false;

	default:
	  return false;
	}
    }

  if (base == NULL_TREE)
    return false;

  ref->ref = NULL_TREE;
  ref->base = base;
  ref->ref_alias_set = set;
  ref->base_alias_set = base_set;
  /* We discount volatiles from value-numbering elsewhere.  */
  ref->volatile_p = false;

  if (!size.to_shwi (&ref->size) || maybe_lt (ref->size, 0))
    {
      ref->offset = 0;
      ref->size = -1;
      ref->max_size = -1;
      return true;
    }

  if (!offset.to_shwi (&ref->offset))
    {
      ref->offset = 0;
      ref->max_size = -1;
      return true;
    }

  if (!max_size.to_shwi (&ref->max_size) || maybe_lt (ref->max_size, 0))
    ref->max_size = -1;

  return true;
}

/* Copy the operations present in load/store/call REF into RESULT, a vector of
   vn_reference_op_s's.  */

static void
copy_reference_ops_from_call (gcall *call,
			      vec<vn_reference_op_s> *result)
{
  vn_reference_op_s temp;
  unsigned i;
  tree lhs = gimple_call_lhs (call);
  int lr;

  /* If 2 calls have a different non-ssa lhs, vdef value numbers should be
     different.  By adding the lhs here in the vector, we ensure that the
     hashcode is different, guaranteeing a different value number.  */
  if (lhs && TREE_CODE (lhs) != SSA_NAME)
    {
      memset (&temp, 0, sizeof (temp));
      temp.opcode = MODIFY_EXPR;
      temp.type = TREE_TYPE (lhs);
      temp.op0 = lhs;
      temp.off = -1;
      result->safe_push (temp);
    }

  /* Copy the type, opcode, function, static chain and EH region, if any.  */
  memset (&temp, 0, sizeof (temp));
  temp.type = gimple_call_fntype (call);
  temp.opcode = CALL_EXPR;
  temp.op0 = gimple_call_fn (call);
  temp.op1 = gimple_call_chain (call);
  if (stmt_could_throw_p (cfun, call) && (lr = lookup_stmt_eh_lp (call)) > 0)
    temp.op2 = size_int (lr);
  temp.off = -1;
  result->safe_push (temp);

  /* Copy the call arguments.  As they can be references as well,
     just chain them together.  */
  for (i = 0; i < gimple_call_num_args (call); ++i)
    {
      tree callarg = gimple_call_arg (call, i);
      copy_reference_ops_from_ref (callarg, result);
    }
}

/* Fold *& at position *I_P in a vn_reference_op_s vector *OPS.  Updates
   *I_P to point to the last element of the replacement.  */
static bool
vn_reference_fold_indirect (vec<vn_reference_op_s> *ops,
			    unsigned int *i_p)
{
  unsigned int i = *i_p;
  vn_reference_op_t op = &(*ops)[i];
  vn_reference_op_t mem_op = &(*ops)[i - 1];
  tree addr_base;
  poly_int64 addr_offset = 0;

  /* The only thing we have to do is from &OBJ.foo.bar add the offset
     from .foo.bar to the preceding MEM_REF offset and replace the
     address with &OBJ.  */
  addr_base = get_addr_base_and_unit_offset_1 (TREE_OPERAND (op->op0, 0),
					       &addr_offset, vn_valueize);
  gcc_checking_assert (addr_base && TREE_CODE (addr_base) != MEM_REF);
  if (addr_base != TREE_OPERAND (op->op0, 0))
    {
      poly_offset_int off
	= (poly_offset_int::from (wi::to_poly_wide (mem_op->op0),
				  SIGNED)
	   + addr_offset);
      mem_op->op0 = wide_int_to_tree (TREE_TYPE (mem_op->op0), off);
      op->op0 = build_fold_addr_expr (addr_base);
      if (tree_fits_shwi_p (mem_op->op0))
	mem_op->off = tree_to_shwi (mem_op->op0);
      else
	mem_op->off = -1;
      return true;
    }
  return false;
}

/* Fold *& at position *I_P in a vn_reference_op_s vector *OPS.  Updates
   *I_P to point to the last element of the replacement.  */
static bool
vn_reference_maybe_forwprop_address (vec<vn_reference_op_s> *ops,
				     unsigned int *i_p)
{
  bool changed = false;
  vn_reference_op_t op;

  do
    {
      unsigned int i = *i_p;
      op = &(*ops)[i];
      vn_reference_op_t mem_op = &(*ops)[i - 1];
      gimple *def_stmt;
      enum tree_code code;
      poly_offset_int off;

      def_stmt = SSA_NAME_DEF_STMT (op->op0);
      if (!is_gimple_assign (def_stmt))
	return changed;

      code = gimple_assign_rhs_code (def_stmt);
      if (code != ADDR_EXPR
	  && code != POINTER_PLUS_EXPR)
	return changed;

      off = poly_offset_int::from (wi::to_poly_wide (mem_op->op0), SIGNED);

      /* The only thing we have to do is from &OBJ.foo.bar add the offset
	 from .foo.bar to the preceding MEM_REF offset and replace the
	 address with &OBJ.  */
      if (code == ADDR_EXPR)
	{
	  tree addr, addr_base;
	  poly_int64 addr_offset;

	  addr = gimple_assign_rhs1 (def_stmt);
	  addr_base = get_addr_base_and_unit_offset_1 (TREE_OPERAND (addr, 0),
						       &addr_offset,
						       vn_valueize);
	  /* If that didn't work because the address isn't invariant propagate
	     the reference tree from the address operation in case the current
	     dereference isn't offsetted.  */
	  if (!addr_base
	      && *i_p == ops->length () - 1
	      && known_eq (off, 0)
	      /* This makes us disable this transform for PRE where the
		 reference ops might be also used for code insertion which
		 is invalid.  */
	      && default_vn_walk_kind == VN_WALKREWRITE)
	    {
	      auto_vec<vn_reference_op_s, 32> tem;
	      copy_reference_ops_from_ref (TREE_OPERAND (addr, 0), &tem);
	      /* Make sure to preserve TBAA info.  The only objects not
		 wrapped in MEM_REFs that can have their address taken are
		 STRING_CSTs.  */
	      if (tem.length () >= 2
		  && tem[tem.length () - 2].opcode == MEM_REF)
		{
		  vn_reference_op_t new_mem_op = &tem[tem.length () - 2];
		  new_mem_op->op0
		      = wide_int_to_tree (TREE_TYPE (mem_op->op0),
					  wi::to_poly_wide (new_mem_op->op0));
		}
	      else
		gcc_assert (tem.last ().opcode == STRING_CST);
	      ops->pop ();
	      ops->pop ();
	      ops->safe_splice (tem);
	      --*i_p;
	      return true;
	    }
	  if (!addr_base
	      || TREE_CODE (addr_base) != MEM_REF
	      || (TREE_CODE (TREE_OPERAND (addr_base, 0)) == SSA_NAME
		  && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (addr_base,
								    0))))
	    return changed;

	  off += addr_offset;
	  off += mem_ref_offset (addr_base);
	  op->op0 = TREE_OPERAND (addr_base, 0);
	}
      else
	{
	  tree ptr, ptroff;
	  ptr = gimple_assign_rhs1 (def_stmt);
	  ptroff = gimple_assign_rhs2 (def_stmt);
	  if (TREE_CODE (ptr) != SSA_NAME
	      || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr)
	      /* Make sure to not endlessly recurse.
		 See gcc.dg/tree-ssa/20040408-1.c for an example.  Can easily
		 happen when we value-number a PHI to its backedge value.  */
	      || SSA_VAL (ptr) == op->op0
	      || !poly_int_tree_p (ptroff))
	    return changed;

	  off += wi::to_poly_offset (ptroff);
	  op->op0 = ptr;
	}

      mem_op->op0 = wide_int_to_tree (TREE_TYPE (mem_op->op0), off);
      if (tree_fits_shwi_p (mem_op->op0))
	mem_op->off = tree_to_shwi (mem_op->op0);
      else
	mem_op->off = -1;
      /* ???  Can end up with endless recursion here!?
	 gcc.c-torture/execute/strcmp-1.c  */
      if (TREE_CODE (op->op0) == SSA_NAME)
	op->op0 = SSA_VAL (op->op0);
      if (TREE_CODE (op->op0) != SSA_NAME)
	op->opcode = TREE_CODE (op->op0);

      changed = true;
    }
  /* Tail-recurse.  */
  while (TREE_CODE (op->op0) == SSA_NAME);

  /* Fold a remaining *&.  */
  if (TREE_CODE (op->op0) == ADDR_EXPR)
    vn_reference_fold_indirect (ops, i_p);

  return changed;
}

/* Optimize the reference REF to a constant if possible or return
   NULL_TREE if not.  */

tree
fully_constant_vn_reference_p (vn_reference_t ref)
{
  vec<vn_reference_op_s> operands = ref->operands;
  vn_reference_op_t op;

  /* Try to simplify the translated expression if it is
     a call to a builtin function with at most two arguments.  */
  op = &operands[0];
  if (op->opcode == CALL_EXPR
      && TREE_CODE (op->op0) == ADDR_EXPR
      && TREE_CODE (TREE_OPERAND (op->op0, 0)) == FUNCTION_DECL
      && fndecl_built_in_p (TREE_OPERAND (op->op0, 0))
      && operands.length () >= 2
      && operands.length () <= 3)
    {
      vn_reference_op_t arg0, arg1 = NULL;
      bool anyconst = false;
      arg0 = &operands[1];
      if (operands.length () > 2)
	arg1 = &operands[2];
      if (TREE_CODE_CLASS (arg0->opcode) == tcc_constant
	  || (arg0->opcode == ADDR_EXPR
	      && is_gimple_min_invariant (arg0->op0)))
	anyconst = true;
      if (arg1
	  && (TREE_CODE_CLASS (arg1->opcode) == tcc_constant
	      || (arg1->opcode == ADDR_EXPR
		  && is_gimple_min_invariant (arg1->op0))))
	anyconst = true;
      if (anyconst)
	{
	  tree folded = build_call_expr (TREE_OPERAND (op->op0, 0),
					 arg1 ? 2 : 1,
					 arg0->op0,
					 arg1 ? arg1->op0 : NULL);
	  if (folded
	      && TREE_CODE (folded) == NOP_EXPR)
	    folded = TREE_OPERAND (folded, 0);
	  if (folded
	      && is_gimple_min_invariant (folded))
	    return folded;
	}
    }

  /* Simplify reads from constants or constant initializers.  */
  else if (BITS_PER_UNIT == 8
	   && COMPLETE_TYPE_P (ref->type)
	   && is_gimple_reg_type (ref->type))
    {
      poly_int64 off = 0;
      HOST_WIDE_INT size;
      if (INTEGRAL_TYPE_P (ref->type))
	size = TYPE_PRECISION (ref->type);
      else if (tree_fits_shwi_p (TYPE_SIZE (ref->type)))
	size = tree_to_shwi (TYPE_SIZE (ref->type));
      else
	return NULL_TREE;
      if (size % BITS_PER_UNIT != 0
	  || size > MAX_BITSIZE_MODE_ANY_MODE)
	return NULL_TREE;
      size /= BITS_PER_UNIT;
      unsigned i;
      for (i = 0; i < operands.length (); ++i)
	{
	  if (TREE_CODE_CLASS (operands[i].opcode) == tcc_constant)
	    {
	      ++i;
	      break;
	    }
	  if (known_eq (operands[i].off, -1))
	    return NULL_TREE;
	  off += operands[i].off;
	  if (operands[i].opcode == MEM_REF)
	    {
	      ++i;
	      break;
	    }
	}
      vn_reference_op_t base = &operands[--i];
      tree ctor = error_mark_node;
      tree decl = NULL_TREE;
      if (TREE_CODE_CLASS (base->opcode) == tcc_constant)
	ctor = base->op0;
      else if (base->opcode == MEM_REF
	       && base[1].opcode == ADDR_EXPR
	       && (TREE_CODE (TREE_OPERAND (base[1].op0, 0)) == VAR_DECL
		   || TREE_CODE (TREE_OPERAND (base[1].op0, 0)) == CONST_DECL
		   || TREE_CODE (TREE_OPERAND (base[1].op0, 0)) == STRING_CST))
	{
	  decl = TREE_OPERAND (base[1].op0, 0);
	  if (TREE_CODE (decl) == STRING_CST)
	    ctor = decl;
	  else
	    ctor = ctor_for_folding (decl);
	}
      if (ctor == NULL_TREE)
	return build_zero_cst (ref->type);
      else if (ctor != error_mark_node)
	{
	  HOST_WIDE_INT const_off;
	  if (decl)
	    {
	      tree res = fold_ctor_reference (ref->type, ctor,
					      off * BITS_PER_UNIT,
					      size * BITS_PER_UNIT, decl);
	      if (res)
		{
		  STRIP_USELESS_TYPE_CONVERSION (res);
		  if (is_gimple_min_invariant (res))
		    return res;
		}
	    }
	  else if (off.is_constant (&const_off))
	    {
	      unsigned char buf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
	      int len = native_encode_expr (ctor, buf, size, const_off);
	      if (len > 0)
		return native_interpret_expr (ref->type, buf, len);
	    }
	}
    }

  return NULL_TREE;
}

/* Return true if OPS contain a storage order barrier.  */

static bool
contains_storage_order_barrier_p (vec<vn_reference_op_s> ops)
{
  vn_reference_op_t op;
  unsigned i;

  FOR_EACH_VEC_ELT (ops, i, op)
    if (op->opcode == VIEW_CONVERT_EXPR && op->reverse)
      return true;

  return false;
}

/* Transform any SSA_NAME's in a vector of vn_reference_op_s
   structures into their value numbers.  This is done in-place, and
   the vector passed in is returned.  *VALUEIZED_ANYTHING will specify
   whether any operands were valueized.  */

static vec<vn_reference_op_s> 
valueize_refs_1 (vec<vn_reference_op_s> orig, bool *valueized_anything,
		 bool with_avail = false)
{
  vn_reference_op_t vro;
  unsigned int i;

  *valueized_anything = false;

  FOR_EACH_VEC_ELT (orig, i, vro)
    {
      if (vro->opcode == SSA_NAME
	  || (vro->op0 && TREE_CODE (vro->op0) == SSA_NAME))
	{
	  tree tem = with_avail ? vn_valueize (vro->op0) : SSA_VAL (vro->op0);
	  if (tem != vro->op0)
	    {
	      *valueized_anything = true;
	      vro->op0 = tem;
	    }
	  /* If it transforms from an SSA_NAME to a constant, update
	     the opcode.  */
	  if (TREE_CODE (vro->op0) != SSA_NAME && vro->opcode == SSA_NAME)
	    vro->opcode = TREE_CODE (vro->op0);
	}
      if (vro->op1 && TREE_CODE (vro->op1) == SSA_NAME)
	{
	  tree tem = with_avail ? vn_valueize (vro->op1) : SSA_VAL (vro->op1);
	  if (tem != vro->op1)
	    {
	      *valueized_anything = true;
	      vro->op1 = tem;
	    }
	}
      if (vro->op2 && TREE_CODE (vro->op2) == SSA_NAME)
	{
	  tree tem = with_avail ? vn_valueize (vro->op2) : SSA_VAL (vro->op2);
	  if (tem != vro->op2)
	    {
	      *valueized_anything = true;
	      vro->op2 = tem;
	    }
	}
      /* If it transforms from an SSA_NAME to an address, fold with
	 a preceding indirect reference.  */
      if (i > 0
	  && vro->op0
	  && TREE_CODE (vro->op0) == ADDR_EXPR
	  && orig[i - 1].opcode == MEM_REF)
	{
	  if (vn_reference_fold_indirect (&orig, &i))
	    *valueized_anything = true;
	}
      else if (i > 0
	       && vro->opcode == SSA_NAME
	       && orig[i - 1].opcode == MEM_REF)
	{
	  if (vn_reference_maybe_forwprop_address (&orig, &i))
	    *valueized_anything = true;
	}
      /* If it transforms a non-constant ARRAY_REF into a constant
	 one, adjust the constant offset.  */
      else if (vro->opcode == ARRAY_REF
	       && known_eq (vro->off, -1)
	       && poly_int_tree_p (vro->op0)
	       && poly_int_tree_p (vro->op1)
	       && TREE_CODE (vro->op2) == INTEGER_CST)
	{
	  poly_offset_int off = ((wi::to_poly_offset (vro->op0)
				  - wi::to_poly_offset (vro->op1))
				 * wi::to_offset (vro->op2)
				 * vn_ref_op_align_unit (vro));
	  off.to_shwi (&vro->off);
	}
    }

  return orig;
}

static vec<vn_reference_op_s> 
valueize_refs (vec<vn_reference_op_s> orig)
{
  bool tem;
  return valueize_refs_1 (orig, &tem);
}

static vec<vn_reference_op_s> shared_lookup_references;

/* Create a vector of vn_reference_op_s structures from REF, a
   REFERENCE_CLASS_P tree.  The vector is shared among all callers of
   this function.  *VALUEIZED_ANYTHING will specify whether any
   operands were valueized.  */

static vec<vn_reference_op_s> 
valueize_shared_reference_ops_from_ref (tree ref, bool *valueized_anything)
{
  if (!ref)
    return vNULL;
  shared_lookup_references.truncate (0);
  copy_reference_ops_from_ref (ref, &shared_lookup_references);
  shared_lookup_references = valueize_refs_1 (shared_lookup_references,
					      valueized_anything);
  return shared_lookup_references;
}

/* Create a vector of vn_reference_op_s structures from CALL, a
   call statement.  The vector is shared among all callers of
   this function.  */

static vec<vn_reference_op_s> 
valueize_shared_reference_ops_from_call (gcall *call)
{
  if (!call)
    return vNULL;
  shared_lookup_references.truncate (0);
  copy_reference_ops_from_call (call, &shared_lookup_references);
  shared_lookup_references = valueize_refs (shared_lookup_references);
  return shared_lookup_references;
}

/* Lookup a SCCVN reference operation VR in the current hash table.
   Returns the resulting value number if it exists in the hash table,
   NULL_TREE otherwise.  VNRESULT will be filled in with the actual
   vn_reference_t stored in the hashtable if something is found.  */

static tree
vn_reference_lookup_1 (vn_reference_t vr, vn_reference_t *vnresult)
{
  vn_reference_s **slot;
  hashval_t hash;

  hash = vr->hashcode;
  slot = valid_info->references->find_slot_with_hash (vr, hash, NO_INSERT);
  if (slot)
    {
      if (vnresult)
	*vnresult = (vn_reference_t)*slot;
      return ((vn_reference_t)*slot)->result;
    }

  return NULL_TREE;
}


/* Partial definition tracking support.  */

struct pd_range
{
  HOST_WIDE_INT offset;
  HOST_WIDE_INT size;
};

struct pd_data
{
  tree rhs;
  HOST_WIDE_INT offset;
  HOST_WIDE_INT size;
};

/* Context for alias walking.  */

struct vn_walk_cb_data
{
  vn_walk_cb_data (vn_reference_t vr_, tree orig_ref_, tree *last_vuse_ptr_,
		   vn_lookup_kind vn_walk_kind_, bool tbaa_p_, tree mask_)
    : vr (vr_), last_vuse_ptr (last_vuse_ptr_), last_vuse (NULL_TREE),
      mask (mask_), masked_result (NULL_TREE), vn_walk_kind (vn_walk_kind_),
      tbaa_p (tbaa_p_), saved_operands (vNULL), first_set (-2),
      first_base_set (-2), known_ranges (NULL)
  {
    if (!last_vuse_ptr)
      last_vuse_ptr = &last_vuse;
    ao_ref_init (&orig_ref, orig_ref_);
    if (mask)
      {
	wide_int w = wi::to_wide (mask);
	unsigned int pos = 0, prec = w.get_precision ();
	pd_data pd;
	pd.rhs = build_constructor (NULL_TREE, NULL);
	/* When bitwise and with a constant is done on a memory load,
	   we don't really need all the bits to be defined or defined
	   to constants, we don't really care what is in the position
	   corresponding to 0 bits in the mask.
	   So, push the ranges of those 0 bits in the mask as artificial
	   zero stores and let the partial def handling code do the
	   rest.  */
	while (pos < prec)
	  {
	    int tz = wi::ctz (w);
	    if (pos + tz > prec)
	      tz = prec - pos;
	    if (tz)
	      {
		if (BYTES_BIG_ENDIAN)
		  pd.offset = prec - pos - tz;
		else
		  pd.offset = pos;
		pd.size = tz;
		void *r = push_partial_def (pd, 0, 0, 0, prec);
		gcc_assert (r == NULL_TREE);
	      }
	    pos += tz;
	    if (pos == prec)
	      break;
	    w = wi::lrshift (w, tz);
	    tz = wi::ctz (wi::bit_not (w));
	    if (pos + tz > prec)
	      tz = prec - pos;
	    pos += tz;
	    w = wi::lrshift (w, tz);
	  }
      }
  }
  ~vn_walk_cb_data ();
  void *finish (alias_set_type, alias_set_type, tree);
  void *push_partial_def (pd_data pd,
			  alias_set_type, alias_set_type, HOST_WIDE_INT,
			  HOST_WIDE_INT);

  vn_reference_t vr;
  ao_ref orig_ref;
  tree *last_vuse_ptr;
  tree last_vuse;
  tree mask;
  tree masked_result;
  vn_lookup_kind vn_walk_kind;
  bool tbaa_p;
  vec<vn_reference_op_s> saved_operands;

  /* The VDEFs of partial defs we come along.  */
  auto_vec<pd_data, 2> partial_defs;
  /* The first defs range to avoid splay tree setup in most cases.  */
  pd_range first_range;
  alias_set_type first_set;
  alias_set_type first_base_set;
  splay_tree known_ranges;
  obstack ranges_obstack;
};

vn_walk_cb_data::~vn_walk_cb_data ()
{
  if (known_ranges)
    {
      splay_tree_delete (known_ranges);
      obstack_free (&ranges_obstack, NULL);
    }
  saved_operands.release ();
}

void *
vn_walk_cb_data::finish (alias_set_type set, alias_set_type base_set, tree val)
{
  if (first_set != -2)
    {
      set = first_set;
      base_set = first_base_set;
    }
  if (mask)
    {
      masked_result = val;
      return (void *) -1;
    }
  vec<vn_reference_op_s> &operands
    = saved_operands.exists () ? saved_operands : vr->operands;
  return vn_reference_lookup_or_insert_for_pieces (last_vuse, set, base_set,
						   vr->type, operands, val);
}

/* pd_range splay-tree helpers.  */

static int
pd_range_compare (splay_tree_key offset1p, splay_tree_key offset2p)
{
  HOST_WIDE_INT offset1 = *(HOST_WIDE_INT *)offset1p;
  HOST_WIDE_INT offset2 = *(HOST_WIDE_INT *)offset2p;
  if (offset1 < offset2)
    return -1;
  else if (offset1 > offset2)
    return 1;
  return 0;
}

static void *
pd_tree_alloc (int size, void *data_)
{
  vn_walk_cb_data *data = (vn_walk_cb_data *)data_;
  return obstack_alloc (&data->ranges_obstack, size);
}

static void
pd_tree_dealloc (void *, void *)
{
}

/* Push PD to the vector of partial definitions returning a
   value when we are ready to combine things with VUSE, SET and MAXSIZEI,
   NULL when we want to continue looking for partial defs or -1
   on failure.  */

void *
vn_walk_cb_data::push_partial_def (pd_data pd,
				   alias_set_type set, alias_set_type base_set,
				   HOST_WIDE_INT offseti,
				   HOST_WIDE_INT maxsizei)
{
  const HOST_WIDE_INT bufsize = 64;
  /* We're using a fixed buffer for encoding so fail early if the object
     we want to interpret is bigger.  */
  if (maxsizei > bufsize * BITS_PER_UNIT
      || CHAR_BIT != 8
      || BITS_PER_UNIT != 8
      /* Not prepared to handle PDP endian.  */
      || BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
    return (void *)-1;

  /* Turn too large constant stores into non-constant stores.  */
  if (CONSTANT_CLASS_P (pd.rhs) && pd.size > bufsize * BITS_PER_UNIT)
    pd.rhs = error_mark_node;

  /* And for non-constant or CONSTRUCTOR stores shrink them to only keep at
     most a partial byte before and/or after the region.  */
  if (!CONSTANT_CLASS_P (pd.rhs))
    {
      if (pd.offset < offseti)
	{
	  HOST_WIDE_INT o = ROUND_DOWN (offseti - pd.offset, BITS_PER_UNIT);
	  gcc_assert (pd.size > o);
	  pd.size -= o;
	  pd.offset += o;
	}
      if (pd.size > maxsizei)
	pd.size = maxsizei + ((pd.size - maxsizei) % BITS_PER_UNIT);
    }

  pd.offset -= offseti;

  bool pd_constant_p = (TREE_CODE (pd.rhs) == CONSTRUCTOR
			|| CONSTANT_CLASS_P (pd.rhs));
  if (partial_defs.is_empty ())
    {
      /* If we get a clobber upfront, fail.  */
      if (TREE_CLOBBER_P (pd.rhs))
	return (void *)-1;
      if (!pd_constant_p)
	return (void *)-1;
      partial_defs.safe_push (pd);
      first_range.offset = pd.offset;
      first_range.size = pd.size;
      first_set = set;
      first_base_set = base_set;
      last_vuse_ptr = NULL;
      /* Continue looking for partial defs.  */
      return NULL;
    }

  if (!known_ranges)
    {
      /* ???  Optimize the case where the 2nd partial def completes things.  */
      gcc_obstack_init (&ranges_obstack);
      known_ranges = splay_tree_new_with_allocator (pd_range_compare, 0, 0,
						    pd_tree_alloc,
						    pd_tree_dealloc, this);
      splay_tree_insert (known_ranges,
			 (splay_tree_key)&first_range.offset,
			 (splay_tree_value)&first_range);
    }

  pd_range newr = { pd.offset, pd.size };
  splay_tree_node n;
  pd_range *r;
  /* Lookup the predecessor of offset + 1 and see if we need to merge.  */
  HOST_WIDE_INT loffset = newr.offset + 1;
  if ((n = splay_tree_predecessor (known_ranges, (splay_tree_key)&loffset))
      && ((r = (pd_range *)n->value), true)
      && ranges_known_overlap_p (r->offset, r->size + 1,
				 newr.offset, newr.size))
    {
      /* Ignore partial defs already covered.  Here we also drop shadowed
         clobbers arriving here at the floor.  */
      if (known_subrange_p (newr.offset, newr.size, r->offset, r->size))
	return NULL;
      r->size = MAX (r->offset + r->size, newr.offset + newr.size) - r->offset;
    }
  else
    {
      /* newr.offset wasn't covered yet, insert the range.  */
      r = XOBNEW (&ranges_obstack, pd_range);
      *r = newr;
      splay_tree_insert (known_ranges, (splay_tree_key)&r->offset,
			 (splay_tree_value)r);
    }
  /* Merge r which now contains newr and is a member of the splay tree with
     adjacent overlapping ranges.  */
  pd_range *rafter;
  while ((n = splay_tree_successor (known_ranges, (splay_tree_key)&r->offset))
	 && ((rafter = (pd_range *)n->value), true)
	 && ranges_known_overlap_p (r->offset, r->size + 1,
				    rafter->offset, rafter->size))
    {
      r->size = MAX (r->offset + r->size,
		     rafter->offset + rafter->size) - r->offset;
      splay_tree_remove (known_ranges, (splay_tree_key)&rafter->offset);
    }
  /* If we get a clobber, fail.  */
  if (TREE_CLOBBER_P (pd.rhs))
    return (void *)-1;
  /* Non-constants are OK as long as they are shadowed by a constant.  */
  if (!pd_constant_p)
    return (void *)-1;
  partial_defs.safe_push (pd);

  /* Now we have merged newr into the range tree.  When we have covered
     [offseti, sizei] then the tree will contain exactly one node which has
     the desired properties and it will be 'r'.  */
  if (!known_subrange_p (0, maxsizei, r->offset, r->size))
    /* Continue looking for partial defs.  */
    return NULL;

  /* Now simply native encode all partial defs in reverse order.  */
  unsigned ndefs = partial_defs.length ();
  /* We support up to 512-bit values (for V8DFmode).  */
  unsigned char buffer[bufsize + 1];
  unsigned char this_buffer[bufsize + 1];
  int len;

  memset (buffer, 0, bufsize + 1);
  unsigned needed_len = ROUND_UP (maxsizei, BITS_PER_UNIT) / BITS_PER_UNIT;
  while (!partial_defs.is_empty ())
    {
      pd_data pd = partial_defs.pop ();
      unsigned int amnt;
      if (TREE_CODE (pd.rhs) == CONSTRUCTOR)
	{
	  /* Empty CONSTRUCTOR.  */
	  if (pd.size >= needed_len * BITS_PER_UNIT)
	    len = needed_len;
	  else
	    len = ROUND_UP (pd.size, BITS_PER_UNIT) / BITS_PER_UNIT;
	  memset (this_buffer, 0, len);
	}
      else
	{
	  len = native_encode_expr (pd.rhs, this_buffer, bufsize,
				    MAX (0, -pd.offset) / BITS_PER_UNIT);
	  if (len <= 0
	      || len < (ROUND_UP (pd.size, BITS_PER_UNIT) / BITS_PER_UNIT
			- MAX (0, -pd.offset) / BITS_PER_UNIT))
	    {
	      if (dump_file && (dump_flags & TDF_DETAILS))
		fprintf (dump_file, "Failed to encode %u "
			 "partial definitions\n", ndefs);
	      return (void *)-1;
	    }
	}

      unsigned char *p = buffer;
      HOST_WIDE_INT size = pd.size;
      if (pd.offset < 0)
	size -= ROUND_DOWN (-pd.offset, BITS_PER_UNIT);
      this_buffer[len] = 0;
      if (BYTES_BIG_ENDIAN)
	{
	  /* LSB of this_buffer[len - 1] byte should be at
	     pd.offset + pd.size - 1 bits in buffer.  */
	  amnt = ((unsigned HOST_WIDE_INT) pd.offset
		  + pd.size) % BITS_PER_UNIT;
	  if (amnt)
	    shift_bytes_in_array_right (this_buffer, len + 1, amnt);
	  unsigned char *q = this_buffer;
	  unsigned int off = 0;
	  if (pd.offset >= 0)
	    {
	      unsigned int msk;
	      off = pd.offset / BITS_PER_UNIT;
	      gcc_assert (off < needed_len);
	      p = buffer + off;
	      if (size <= amnt)
		{
		  msk = ((1 << size) - 1) << (BITS_PER_UNIT - amnt);
		  *p = (*p & ~msk) | (this_buffer[len] & msk);
		  size = 0;
		}
	      else
		{
		  if (TREE_CODE (pd.rhs) != CONSTRUCTOR)
		    q = (this_buffer + len
			 - (ROUND_UP (size - amnt, BITS_PER_UNIT)
			    / BITS_PER_UNIT));
		  if (pd.offset % BITS_PER_UNIT)
		    {
		      msk = -1U << (BITS_PER_UNIT
				    - (pd.offset % BITS_PER_UNIT));
		      *p = (*p & msk) | (*q & ~msk);
		      p++;
		      q++;
		      off++;
		      size -= BITS_PER_UNIT - (pd.offset % BITS_PER_UNIT);
		      gcc_assert (size >= 0);
		    }
		}
	    }
	  else if (TREE_CODE (pd.rhs) != CONSTRUCTOR)
	    {
	      q = (this_buffer + len
		   - (ROUND_UP (size - amnt, BITS_PER_UNIT)
		      / BITS_PER_UNIT));
	      if (pd.offset % BITS_PER_UNIT)
		{
		  q++;
		  size -= BITS_PER_UNIT - ((unsigned HOST_WIDE_INT) pd.offset
					   % BITS_PER_UNIT);
		  gcc_assert (size >= 0);
		}
	    }
	  if ((unsigned HOST_WIDE_INT) size / BITS_PER_UNIT + off
	      > needed_len)
	    size = (needed_len - off) * BITS_PER_UNIT;
	  memcpy (p, q, size / BITS_PER_UNIT);
	  if (size % BITS_PER_UNIT)
	    {
	      unsigned int msk
		= -1U << (BITS_PER_UNIT - (size % BITS_PER_UNIT));
	      p += size / BITS_PER_UNIT;
	      q += size / BITS_PER_UNIT;
	      *p = (*q & msk) | (*p & ~msk);
	    }
	}
      else
	{
	  size = MIN (size, (HOST_WIDE_INT) needed_len * BITS_PER_UNIT);
	  if (pd.offset >= 0)
	    {
	      /* LSB of this_buffer[0] byte should be at pd.offset bits
		 in buffer.  */
	      unsigned int msk;
	      amnt = pd.offset % BITS_PER_UNIT;
	      if (amnt)
		shift_bytes_in_array_left (this_buffer, len + 1, amnt);
	      unsigned int off = pd.offset / BITS_PER_UNIT;
	      gcc_assert (off < needed_len);
	      size = MIN (size,
			  (HOST_WIDE_INT) (needed_len - off) * BITS_PER_UNIT);
	      p = buffer + off;
	      if (amnt + size < BITS_PER_UNIT)
		{
		  /* Low amnt bits come from *p, then size bits
		     from this_buffer[0] and the remaining again from
		     *p.  */
		  msk = ((1 << size) - 1) << amnt;
		  *p = (*p & ~msk) | (this_buffer[0] & msk);
		  size = 0;
		}
	      else if (amnt)
		{
		  msk = -1U << amnt;
		  *p = (*p & ~msk) | (this_buffer[0] & msk);
		  p++;
		  size -= (BITS_PER_UNIT - amnt);
		}
	    }
	  else
	    {
	      amnt = (unsigned HOST_WIDE_INT) pd.offset % BITS_PER_UNIT;
	      if (amnt)
		shift_bytes_in_array_left (this_buffer, len + 1, amnt);
	    }
	  memcpy (p, this_buffer + (amnt != 0), size / BITS_PER_UNIT);
	  p += size / BITS_PER_UNIT;
	  if (size % BITS_PER_UNIT)
	    {
	      unsigned int msk = -1U << (size % BITS_PER_UNIT);
	      *p = (this_buffer[(amnt != 0) + size / BITS_PER_UNIT]
		    & ~msk) | (*p & msk);
	    }
	}
    }

  tree type = vr->type;
  /* Make sure to interpret in a type that has a range covering the whole
     access size.  */
  if (INTEGRAL_TYPE_P (vr->type) && maxsizei != TYPE_PRECISION (vr->type))
    type = build_nonstandard_integer_type (maxsizei, TYPE_UNSIGNED (type));
  tree val;
  if (BYTES_BIG_ENDIAN)
    {
      unsigned sz = needed_len;
      if (maxsizei % BITS_PER_UNIT)
	shift_bytes_in_array_right (buffer, needed_len,
				    BITS_PER_UNIT
				    - (maxsizei % BITS_PER_UNIT));
      if (INTEGRAL_TYPE_P (type))
	sz = GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (type));
      if (sz > needed_len)
	{
	  memcpy (this_buffer + (sz - needed_len), buffer, needed_len);
	  val = native_interpret_expr (type, this_buffer, sz);
	}
      else
	val = native_interpret_expr (type, buffer, needed_len);
    }
  else
    val = native_interpret_expr (type, buffer, bufsize);
  /* If we chop off bits because the types precision doesn't match the memory
     access size this is ok when optimizing reads but not when called from
     the DSE code during elimination.  */
  if (val && type != vr->type)
    {
      if (! int_fits_type_p (val, vr->type))
	val = NULL_TREE;
      else
	val = fold_convert (vr->type, val);
    }

  if (val)
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file,
		 "Successfully combined %u partial definitions\n", ndefs);
      /* We are using the alias-set of the first store we encounter which
	 should be appropriate here.  */
      return finish (first_set, first_base_set, val);
    }
  else
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file,
		 "Failed to interpret %u encoded partial definitions\n", ndefs);
      return (void *)-1;
    }
}

/* Callback for walk_non_aliased_vuses.  Adjusts the vn_reference_t VR_
   with the current VUSE and performs the expression lookup.  */

static void *
vn_reference_lookup_2 (ao_ref *op ATTRIBUTE_UNUSED, tree vuse, void *data_)
{
  vn_walk_cb_data *data = (vn_walk_cb_data *)data_;
  vn_reference_t vr = data->vr;
  vn_reference_s **slot;
  hashval_t hash;

  /* If we have partial definitions recorded we have to go through
     vn_reference_lookup_3.  */
  if (!data->partial_defs.is_empty ())
    return NULL;

  if (data->last_vuse_ptr)
    {
      *data->last_vuse_ptr = vuse;
      data->last_vuse = vuse;
    }

  /* Fixup vuse and hash.  */
  if (vr->vuse)
    vr->hashcode = vr->hashcode - SSA_NAME_VERSION (vr->vuse);
  vr->vuse = vuse_ssa_val (vuse);
  if (vr->vuse)
    vr->hashcode = vr->hashcode + SSA_NAME_VERSION (vr->vuse);

  hash = vr->hashcode;
  slot = valid_info->references->find_slot_with_hash (vr, hash, NO_INSERT);
  if (slot)
    {
      if ((*slot)->result && data->saved_operands.exists ())
	return data->finish (vr->set, vr->base_set, (*slot)->result);
      return *slot;
    }

  return NULL;
}

/* Lookup an existing or insert a new vn_reference entry into the
   value table for the VUSE, SET, TYPE, OPERANDS reference which
   has the value VALUE which is either a constant or an SSA name.  */

static vn_reference_t
vn_reference_lookup_or_insert_for_pieces (tree vuse,
					  alias_set_type set,
					  alias_set_type base_set,
					  tree type,
					  vec<vn_reference_op_s,
					        va_heap> operands,
					  tree value)
{
  vn_reference_s vr1;
  vn_reference_t result;
  unsigned value_id;
  vr1.vuse = vuse ? SSA_VAL (vuse) : NULL_TREE;
  vr1.operands = operands;
  vr1.type = type;
  vr1.set = set;
  vr1.base_set = base_set;
  vr1.hashcode = vn_reference_compute_hash (&vr1);
  if (vn_reference_lookup_1 (&vr1, &result))
    return result;
  if (TREE_CODE (value) == SSA_NAME)
    value_id = VN_INFO (value)->value_id;
  else
    value_id = get_or_alloc_constant_value_id (value);
  return vn_reference_insert_pieces (vuse, set, base_set, type,
				     operands.copy (), value, value_id);
}

/* Return a value-number for RCODE OPS... either by looking up an existing
   value-number for the simplified result or by inserting the operation if
   INSERT is true.  */

static tree
vn_nary_build_or_lookup_1 (gimple_match_op *res_op, bool insert)
{
  tree result = NULL_TREE;
  /* We will be creating a value number for
       RCODE (OPS...).
     So first simplify and lookup this expression to see if it
     is already available.  */
  /* For simplification valueize.  */
  unsigned i;
  for (i = 0; i < res_op->num_ops; ++i)
    if (TREE_CODE (res_op->ops[i]) == SSA_NAME)
      {
	tree tem = vn_valueize (res_op->ops[i]);
	if (!tem)
	  break;
	res_op->ops[i] = tem;
      }
  /* If valueization of an operand fails (it is not available), skip
     simplification.  */
  bool res = false;
  if (i == res_op->num_ops)
    {
      mprts_hook = vn_lookup_simplify_result;
      res = res_op->resimplify (NULL, vn_valueize);
      mprts_hook = NULL;
    }
  gimple *new_stmt = NULL;
  if (res
      && gimple_simplified_result_is_gimple_val (res_op))
    {
      /* The expression is already available.  */
      result = res_op->ops[0];
      /* Valueize it, simplification returns sth in AVAIL only.  */
      if (TREE_CODE (result) == SSA_NAME)
	result = SSA_VAL (result);
    }
  else
    {
      tree val = vn_lookup_simplify_result (res_op);
      if (!val && insert)
	{
	  gimple_seq stmts = NULL;
	  result = maybe_push_res_to_seq (res_op, &stmts);
	  if (result)
	    {
	      gcc_assert (gimple_seq_singleton_p (stmts));
	      new_stmt = gimple_seq_first_stmt (stmts);
	    }
	}
      else
	/* The expression is already available.  */
	result = val;
    }
  if (new_stmt)
    {
      /* The expression is not yet available, value-number lhs to
	 the new SSA_NAME we created.  */
      /* Initialize value-number information properly.  */
      vn_ssa_aux_t result_info = VN_INFO (result);
      result_info->valnum = result;
      result_info->value_id = get_next_value_id ();
      result_info->visited = 1;
      gimple_seq_add_stmt_without_update (&VN_INFO (result)->expr,
					  new_stmt);
      result_info->needs_insertion = true;
      /* ???  PRE phi-translation inserts NARYs without corresponding
         SSA name result.  Re-use those but set their result according
	 to the stmt we just built.  */
      vn_nary_op_t nary = NULL;
      vn_nary_op_lookup_stmt (new_stmt, &nary);
      if (nary)
	{
	  gcc_assert (! nary->predicated_values && nary->u.result == NULL_TREE);
	  nary->u.result = gimple_assign_lhs (new_stmt);
	}
      /* As all "inserted" statements are singleton SCCs, insert
	 to the valid table.  This is strictly needed to
	 avoid re-generating new value SSA_NAMEs for the same
	 expression during SCC iteration over and over (the
	 optimistic table gets cleared after each iteration).
	 We do not need to insert into the optimistic table, as
	 lookups there will fall back to the valid table.  */
      else
	{
	  unsigned int length = vn_nary_length_from_stmt (new_stmt);
	  vn_nary_op_t vno1
	    = alloc_vn_nary_op_noinit (length, &vn_tables_insert_obstack);
	  vno1->value_id = result_info->value_id;
	  vno1->length = length;
	  vno1->predicated_values = 0;
	  vno1->u.result = result;
	  init_vn_nary_op_from_stmt (vno1, new_stmt);
	  vn_nary_op_insert_into (vno1, valid_info->nary, true);
	  /* Also do not link it into the undo chain.  */
	  last_inserted_nary = vno1->next;
	  vno1->next = (vn_nary_op_t)(void *)-1;
	}
      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "Inserting name ");
	  print_generic_expr (dump_file, result);
	  fprintf (dump_file, " for expression ");
	  print_gimple_expr (dump_file, new_stmt, 0, TDF_SLIM);
	  fprintf (dump_file, "\n");
	}
    }
  return result;
}

/* Return a value-number for RCODE OPS... either by looking up an existing
   value-number for the simplified result or by inserting the operation.  */

static tree
vn_nary_build_or_lookup (gimple_match_op *res_op)
{
  return vn_nary_build_or_lookup_1 (res_op, true);
}

/* Try to simplify the expression RCODE OPS... of type TYPE and return
   its value if present.  */

tree
vn_nary_simplify (vn_nary_op_t nary)
{
  if (nary->length > gimple_match_op::MAX_NUM_OPS)
    return NULL_TREE;
  gimple_match_op op (gimple_match_cond::UNCOND, nary->opcode,
		      nary->type, nary->length);
  memcpy (op.ops, nary->op, sizeof (tree) * nary->length);
  return vn_nary_build_or_lookup_1 (&op, false);
}

/* Elimination engine.  */

class eliminate_dom_walker : public dom_walker
{
public:
  eliminate_dom_walker (cdi_direction, bitmap);
  ~eliminate_dom_walker ();

  virtual edge before_dom_children (basic_block);
  virtual void after_dom_children (basic_block);

  virtual tree eliminate_avail (basic_block, tree op);
  virtual void eliminate_push_avail (basic_block, tree op);
  tree eliminate_insert (basic_block, gimple_stmt_iterator *gsi, tree val);

  void eliminate_stmt (basic_block, gimple_stmt_iterator *);

  unsigned eliminate_cleanup (bool region_p = false);

  bool do_pre;
  unsigned int el_todo;
  unsigned int eliminations;
  unsigned int insertions;

  /* SSA names that had their defs inserted by PRE if do_pre.  */
  bitmap inserted_exprs;

  /* Blocks with statements that have had their EH properties changed.  */
  bitmap need_eh_cleanup;

  /* Blocks with statements that have had their AB properties changed.  */
  bitmap need_ab_cleanup;

  /* Local state for the eliminate domwalk.  */
  auto_vec<gimple *> to_remove;
  auto_vec<gimple *> to_fixup;
  auto_vec<tree> avail;
  auto_vec<tree> avail_stack;
};

/* Adaptor to the elimination engine using RPO availability.  */

class rpo_elim : public eliminate_dom_walker
{
public:
  rpo_elim(basic_block entry_)
    : eliminate_dom_walker (CDI_DOMINATORS, NULL), entry (entry_),
      m_avail_freelist (NULL) {}

  virtual tree eliminate_avail (basic_block, tree op);

  virtual void eliminate_push_avail (basic_block, tree);

  basic_block entry;
  /* Freelist of avail entries which are allocated from the vn_ssa_aux
     obstack.  */
  vn_avail *m_avail_freelist;
};

/* Global RPO state for access from hooks.  */
static eliminate_dom_walker *rpo_avail;
basic_block vn_context_bb;

/* Return true if BASE1 and BASE2 can be adjusted so they have the
   same address and adjust *OFFSET1 and *OFFSET2 accordingly.
   Otherwise return false.  */

static bool
adjust_offsets_for_equal_base_address (tree base1, poly_int64 *offset1,
				       tree base2, poly_int64 *offset2)
{
  poly_int64 soff;
  if (TREE_CODE (base1) == MEM_REF
      && TREE_CODE (base2) == MEM_REF)
    {
      if (mem_ref_offset (base1).to_shwi (&soff))
	{
	  base1 = TREE_OPERAND (base1, 0);
	  *offset1 += soff * BITS_PER_UNIT;
	}
      if (mem_ref_offset (base2).to_shwi (&soff))
	{
	  base2 = TREE_OPERAND (base2, 0);
	  *offset2 += soff * BITS_PER_UNIT;
	}
      return operand_equal_p (base1, base2, 0);
    }
  return operand_equal_p (base1, base2, OEP_ADDRESS_OF);
}

/* Callback for walk_non_aliased_vuses.  Tries to perform a lookup
   from the statement defining VUSE and if not successful tries to
   translate *REFP and VR_ through an aggregate copy at the definition
   of VUSE.  If *DISAMBIGUATE_ONLY is true then do not perform translation
   of *REF and *VR.  If only disambiguation was performed then
   *DISAMBIGUATE_ONLY is set to true.  */

static void *
vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
		       translate_flags *disambiguate_only)
{
  vn_walk_cb_data *data = (vn_walk_cb_data *)data_;
  vn_reference_t vr = data->vr;
  gimple *def_stmt = SSA_NAME_DEF_STMT (vuse);
  tree base = ao_ref_base (ref);
  HOST_WIDE_INT offseti = 0, maxsizei, sizei = 0;
  static vec<vn_reference_op_s> lhs_ops;
  ao_ref lhs_ref;
  bool lhs_ref_ok = false;
  poly_int64 copy_size;

  /* First try to disambiguate after value-replacing in the definitions LHS.  */
  if (is_gimple_assign (def_stmt))
    {
      tree lhs = gimple_assign_lhs (def_stmt);
      bool valueized_anything = false;
      /* Avoid re-allocation overhead.  */
      lhs_ops.truncate (0);
      basic_block saved_rpo_bb = vn_context_bb;
      vn_context_bb = gimple_bb (def_stmt);
      if (*disambiguate_only <= TR_VALUEIZE_AND_DISAMBIGUATE)
	{
	  copy_reference_ops_from_ref (lhs, &lhs_ops);
	  lhs_ops = valueize_refs_1 (lhs_ops, &valueized_anything, true);
	}
      vn_context_bb = saved_rpo_bb;
      ao_ref_init (&lhs_ref, lhs);
      lhs_ref_ok = true;
      if (valueized_anything
	  && ao_ref_init_from_vn_reference
	       (&lhs_ref, ao_ref_alias_set (&lhs_ref),
		ao_ref_base_alias_set (&lhs_ref), TREE_TYPE (lhs), lhs_ops)
	  && !refs_may_alias_p_1 (ref, &lhs_ref, data->tbaa_p))
	{
	  *disambiguate_only = TR_VALUEIZE_AND_DISAMBIGUATE;
	  return NULL;
	}

      /* Besides valueizing the LHS we can also use access-path based
         disambiguation on the original non-valueized ref.  */
      if (!ref->ref
	  && lhs_ref_ok
	  && data->orig_ref.ref)
	{
	  /* We want to use the non-valueized LHS for this, but avoid redundant
	     work.  */
	  ao_ref *lref = &lhs_ref;
	  ao_ref lref_alt;
	  if (valueized_anything)
	    {
	      ao_ref_init (&lref_alt, lhs);
	      lref = &lref_alt;
	    }
	  if (!refs_may_alias_p_1 (&data->orig_ref, lref, data->tbaa_p))
	    {
	      *disambiguate_only = (valueized_anything
				    ? TR_VALUEIZE_AND_DISAMBIGUATE
				    : TR_DISAMBIGUATE);
	      return NULL;
	    }
	}

      /* If we reach a clobbering statement try to skip it and see if
         we find a VN result with exactly the same value as the
	 possible clobber.  In this case we can ignore the clobber
	 and return the found value.  */
      if (is_gimple_reg_type (TREE_TYPE (lhs))
	  && types_compatible_p (TREE_TYPE (lhs), vr->type)
	  && (ref->ref || data->orig_ref.ref))
	{
	  tree *saved_last_vuse_ptr = data->last_vuse_ptr;
	  /* Do not update last_vuse_ptr in vn_reference_lookup_2.  */
	  data->last_vuse_ptr = NULL;
	  tree saved_vuse = vr->vuse;
	  hashval_t saved_hashcode = vr->hashcode;
	  void *res = vn_reference_lookup_2 (ref, gimple_vuse (def_stmt), data);
	  /* Need to restore vr->vuse and vr->hashcode.  */
	  vr->vuse = saved_vuse;
	  vr->hashcode = saved_hashcode;
	  data->last_vuse_ptr = saved_last_vuse_ptr;
	  if (res && res != (void *)-1)
	    {
	      vn_reference_t vnresult = (vn_reference_t) res;
	      tree rhs = gimple_assign_rhs1 (def_stmt);
	      if (TREE_CODE (rhs) == SSA_NAME)
		rhs = SSA_VAL (rhs);
	      if (vnresult->result
		  && operand_equal_p (vnresult->result, rhs, 0)
		  /* We have to honor our promise about union type punning
		     and also support arbitrary overlaps with
		     -fno-strict-aliasing.  So simply resort to alignment to
		     rule out overlaps.  Do this check last because it is
		     quite expensive compared to the hash-lookup above.  */
		  && multiple_p (get_object_alignment
				   (ref->ref ? ref->ref : data->orig_ref.ref),
				 ref->size)
		  && multiple_p (get_object_alignment (lhs), ref->size))
		return res;
	    }
	}
    }
  else if (*disambiguate_only <= TR_VALUEIZE_AND_DISAMBIGUATE
	   && gimple_call_builtin_p (def_stmt, BUILT_IN_NORMAL)
	   && gimple_call_num_args (def_stmt) <= 4)
    {
      /* For builtin calls valueize its arguments and call the
         alias oracle again.  Valueization may improve points-to
	 info of pointers and constify size and position arguments.
	 Originally this was motivated by PR61034 which has
	 conditional calls to free falsely clobbering ref because
	 of imprecise points-to info of the argument.  */
      tree oldargs[4];
      bool valueized_anything = false;
      for (unsigned i = 0; i < gimple_call_num_args (def_stmt); ++i)
	{
	  oldargs[i] = gimple_call_arg (def_stmt, i);
	  tree val = vn_valueize (oldargs[i]);
	  if (val != oldargs[i])
	    {
	      gimple_call_set_arg (def_stmt, i, val);
	      valueized_anything = true;
	    }
	}
      if (valueized_anything)
	{
	  bool res = call_may_clobber_ref_p_1 (as_a <gcall *> (def_stmt),
					       ref);
	  for (unsigned i = 0; i < gimple_call_num_args (def_stmt); ++i)
	    gimple_call_set_arg (def_stmt, i, oldargs[i]);
	  if (!res)
	    {
	      *disambiguate_only = TR_VALUEIZE_AND_DISAMBIGUATE;
	      return NULL;
	    }
	}
    }

  if (*disambiguate_only > TR_TRANSLATE)
    return (void *)-1;

  /* If we cannot constrain the size of the reference we cannot
     test if anything kills it.  */
  if (!ref->max_size_known_p ())
    return (void *)-1;

  poly_int64 offset = ref->offset;
  poly_int64 maxsize = ref->max_size;

  /* def_stmt may-defs *ref.  See if we can derive a value for *ref
     from that definition.
     1) Memset.  */
  if (is_gimple_reg_type (vr->type)
      && (gimple_call_builtin_p (def_stmt, BUILT_IN_MEMSET)
	  || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMSET_CHK))
      && (integer_zerop (gimple_call_arg (def_stmt, 1))
	  || ((TREE_CODE (gimple_call_arg (def_stmt, 1)) == INTEGER_CST
	       || (INTEGRAL_TYPE_P (vr->type) && known_eq (ref->size, 8)))
	      && CHAR_BIT == 8
	      && BITS_PER_UNIT == 8
	      && BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN
	      && offset.is_constant (&offseti)
	      && ref->size.is_constant (&sizei)
	      && (offseti % BITS_PER_UNIT == 0
		  || TREE_CODE (gimple_call_arg (def_stmt, 1)) == INTEGER_CST)))
      && (poly_int_tree_p (gimple_call_arg (def_stmt, 2))
	  || (TREE_CODE (gimple_call_arg (def_stmt, 2)) == SSA_NAME
	      && poly_int_tree_p (SSA_VAL (gimple_call_arg (def_stmt, 2)))))
      && (TREE_CODE (gimple_call_arg (def_stmt, 0)) == ADDR_EXPR
	  || TREE_CODE (gimple_call_arg (def_stmt, 0)) == SSA_NAME))
    {
      tree base2;
      poly_int64 offset2, size2, maxsize2;
      bool reverse;
      tree ref2 = gimple_call_arg (def_stmt, 0);
      if (TREE_CODE (ref2) == SSA_NAME)
	{
	  ref2 = SSA_VAL (ref2);
	  if (TREE_CODE (ref2) == SSA_NAME
	      && (TREE_CODE (base) != MEM_REF
		  || TREE_OPERAND (base, 0) != ref2))
	    {
	      gimple *def_stmt = SSA_NAME_DEF_STMT (ref2);
	      if (gimple_assign_single_p (def_stmt)
		  && gimple_assign_rhs_code (def_stmt) == ADDR_EXPR)
		ref2 = gimple_assign_rhs1 (def_stmt);
	    }
	}
      if (TREE_CODE (ref2) == ADDR_EXPR)
	{
	  ref2 = TREE_OPERAND (ref2, 0);
	  base2 = get_ref_base_and_extent (ref2, &offset2, &size2, &maxsize2,
					   &reverse);
	  if (!known_size_p (maxsize2)
	      || !known_eq (maxsize2, size2)
	      || !operand_equal_p (base, base2, OEP_ADDRESS_OF))
	    return (void *)-1;
	}
      else if (TREE_CODE (ref2) == SSA_NAME)
	{
	  poly_int64 soff;
	  if (TREE_CODE (base) != MEM_REF
	      || !(mem_ref_offset (base)
		   << LOG2_BITS_PER_UNIT).to_shwi (&soff))
	    return (void *)-1;
	  offset += soff;
	  offset2 = 0;
	  if (TREE_OPERAND (base, 0) != ref2)
	    {
	      gimple *def = SSA_NAME_DEF_STMT (ref2);
	      if (is_gimple_assign (def)
		  && gimple_assign_rhs_code (def) == POINTER_PLUS_EXPR
		  && gimple_assign_rhs1 (def) == TREE_OPERAND (base, 0)
		  && poly_int_tree_p (gimple_assign_rhs2 (def)))
		{
		  tree rhs2 = gimple_assign_rhs2 (def);
		  if (!(poly_offset_int::from (wi::to_poly_wide (rhs2),
					       SIGNED)
			<< LOG2_BITS_PER_UNIT).to_shwi (&offset2))
		    return (void *)-1;
		  ref2 = gimple_assign_rhs1 (def);
		  if (TREE_CODE (ref2) == SSA_NAME)
		    ref2 = SSA_VAL (ref2);
		}
	      else
		return (void *)-1;
	    }
	}
      else
	return (void *)-1;
      tree len = gimple_call_arg (def_stmt, 2);
      HOST_WIDE_INT leni, offset2i;
      if (TREE_CODE (len) == SSA_NAME)
	len = SSA_VAL (len);
      /* Sometimes the above trickery is smarter than alias analysis.  Take
         advantage of that.  */
      if (!ranges_maybe_overlap_p (offset, maxsize, offset2,
				   (wi::to_poly_offset (len)
				    << LOG2_BITS_PER_UNIT)))
	return NULL;
      if (data->partial_defs.is_empty ()
	  && known_subrange_p (offset, maxsize, offset2,
			       wi::to_poly_offset (len) << LOG2_BITS_PER_UNIT))
	{
	  tree val;
	  if (integer_zerop (gimple_call_arg (def_stmt, 1)))
	    val = build_zero_cst (vr->type);
	  else if (INTEGRAL_TYPE_P (vr->type)
		   && known_eq (ref->size, 8)
		   && offseti % BITS_PER_UNIT == 0)
	    {
	      gimple_match_op res_op (gimple_match_cond::UNCOND, NOP_EXPR,
				      vr->type, gimple_call_arg (def_stmt, 1));
	      val = vn_nary_build_or_lookup (&res_op);
	      if (!val
		  || (TREE_CODE (val) == SSA_NAME
		      && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val)))
		return (void *)-1;
	    }
	  else
	    {
	      unsigned buflen = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (vr->type)) + 1;
	      if (INTEGRAL_TYPE_P (vr->type))
		buflen = GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (vr->type)) + 1;
	      unsigned char *buf = XALLOCAVEC (unsigned char, buflen);
	      memset (buf, TREE_INT_CST_LOW (gimple_call_arg (def_stmt, 1)),
		      buflen);
	      if (BYTES_BIG_ENDIAN)
		{
		  unsigned int amnt
		    = (((unsigned HOST_WIDE_INT) offseti + sizei)
		       % BITS_PER_UNIT);
		  if (amnt)
		    {
		      shift_bytes_in_array_right (buf, buflen,
						  BITS_PER_UNIT - amnt);
		      buf++;
		      buflen--;
		    }
		}
	      else if (offseti % BITS_PER_UNIT != 0)
		{
		  unsigned int amnt
		    = BITS_PER_UNIT - ((unsigned HOST_WIDE_INT) offseti
				       % BITS_PER_UNIT);
		  shift_bytes_in_array_left (buf, buflen, amnt);
		  buf++;
		  buflen--;
		}
	      val = native_interpret_expr (vr->type, buf, buflen);
	      if (!val)
		return (void *)-1;
	    }
	  return data->finish (0, 0, val);
	}
      /* For now handle clearing memory with partial defs.  */
      else if (known_eq (ref->size, maxsize)
	       && integer_zerop (gimple_call_arg (def_stmt, 1))
	       && tree_fits_poly_int64_p (len)
	       && tree_to_poly_int64 (len).is_constant (&leni)
	       && leni <= INTTYPE_MAXIMUM (HOST_WIDE_INT) / BITS_PER_UNIT
	       && offset.is_constant (&offseti)
	       && offset2.is_constant (&offset2i)
	       && maxsize.is_constant (&maxsizei)
	       && ranges_known_overlap_p (offseti, maxsizei, offset2i,
					  leni << LOG2_BITS_PER_UNIT))
	{
	  pd_data pd;
	  pd.rhs = build_constructor (NULL_TREE, NULL);
	  pd.offset = offset2i;
	  pd.size = leni << LOG2_BITS_PER_UNIT;
	  return data->push_partial_def (pd, 0, 0, offseti, maxsizei);
	}
    }

  /* 2) Assignment from an empty CONSTRUCTOR.  */
  else if (is_gimple_reg_type (vr->type)
	   && gimple_assign_single_p (def_stmt)
	   && gimple_assign_rhs_code (def_stmt) == CONSTRUCTOR
	   && CONSTRUCTOR_NELTS (gimple_assign_rhs1 (def_stmt)) == 0)
    {
      tree base2;
      poly_int64 offset2, size2, maxsize2;
      HOST_WIDE_INT offset2i, size2i;
      gcc_assert (lhs_ref_ok);
      base2 = ao_ref_base (&lhs_ref);
      offset2 = lhs_ref.offset;
      size2 = lhs_ref.size;
      maxsize2 = lhs_ref.max_size;
      if (known_size_p (maxsize2)
	  && known_eq (maxsize2, size2)
	  && adjust_offsets_for_equal_base_address (base, &offset,
						    base2, &offset2))
	{
	  if (data->partial_defs.is_empty ()
	      && known_subrange_p (offset, maxsize, offset2, size2))
	    {
	      /* While technically undefined behavior do not optimize
	         a full read from a clobber.  */
	      if (gimple_clobber_p (def_stmt))
		return (void *)-1;
	      tree val = build_zero_cst (vr->type);
	      return data->finish (ao_ref_alias_set (&lhs_ref),
				   ao_ref_base_alias_set (&lhs_ref), val);
	    }
	  else if (known_eq (ref->size, maxsize)
		   && maxsize.is_constant (&maxsizei)
		   && offset.is_constant (&offseti)
		   && offset2.is_constant (&offset2i)
		   && size2.is_constant (&size2i)
		   && ranges_known_overlap_p (offseti, maxsizei,
					      offset2i, size2i))
	    {
	      /* Let clobbers be consumed by the partial-def tracker
	         which can choose to ignore them if they are shadowed
		 by a later def.  */
	      pd_data pd;
	      pd.rhs = gimple_assign_rhs1 (def_stmt);
	      pd.offset = offset2i;
	      pd.size = size2i;
	      return data->push_partial_def (pd, ao_ref_alias_set (&lhs_ref),
					     ao_ref_base_alias_set (&lhs_ref),
					     offseti, maxsizei);
	    }
	}
    }

  /* 3) Assignment from a constant.  We can use folds native encode/interpret
     routines to extract the assigned bits.  */
  else if (known_eq (ref->size, maxsize)
	   && is_gimple_reg_type (vr->type)
	   && !contains_storage_order_barrier_p (vr->operands)
	   && gimple_assign_single_p (def_stmt)
	   && CHAR_BIT == 8
	   && BITS_PER_UNIT == 8
	   && BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN
	   /* native_encode and native_decode operate on arrays of bytes
	      and so fundamentally need a compile-time size and offset.  */
	   && maxsize.is_constant (&maxsizei)
	   && offset.is_constant (&offseti)
	   && (is_gimple_min_invariant (gimple_assign_rhs1 (def_stmt))
	       || (TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
		   && is_gimple_min_invariant (SSA_VAL (gimple_assign_rhs1 (def_stmt))))))
    {
      tree lhs = gimple_assign_lhs (def_stmt);
      tree base2;
      poly_int64 offset2, size2, maxsize2;
      HOST_WIDE_INT offset2i, size2i;
      bool reverse;
      gcc_assert (lhs_ref_ok);
      base2 = ao_ref_base (&lhs_ref);
      offset2 = lhs_ref.offset;
      size2 = lhs_ref.size;
      maxsize2 = lhs_ref.max_size;
      reverse = reverse_storage_order_for_component_p (lhs);
      if (base2
	  && !reverse
	  && !storage_order_barrier_p (lhs)
	  && known_eq (maxsize2, size2)
	  && adjust_offsets_for_equal_base_address (base, &offset,
						    base2, &offset2)
	  && offset.is_constant (&offseti)
	  && offset2.is_constant (&offset2i)
	  && size2.is_constant (&size2i))
	{
	  if (data->partial_defs.is_empty ()
	      && known_subrange_p (offseti, maxsizei, offset2, size2))
	    {
	      /* We support up to 512-bit values (for V8DFmode).  */
	      unsigned char buffer[65];
	      int len;

	      tree rhs = gimple_assign_rhs1 (def_stmt);
	      if (TREE_CODE (rhs) == SSA_NAME)
		rhs = SSA_VAL (rhs);
	      len = native_encode_expr (rhs,
					buffer, sizeof (buffer) - 1,
					(offseti - offset2i) / BITS_PER_UNIT);
	      if (len > 0 && len * BITS_PER_UNIT >= maxsizei)
		{
		  tree type = vr->type;
		  unsigned char *buf = buffer;
		  unsigned int amnt = 0;
		  /* Make sure to interpret in a type that has a range
		     covering the whole access size.  */
		  if (INTEGRAL_TYPE_P (vr->type)
		      && maxsizei != TYPE_PRECISION (vr->type))
		    type = build_nonstandard_integer_type (maxsizei,
							   TYPE_UNSIGNED (type));
		  if (BYTES_BIG_ENDIAN)
		    {
		      /* For big-endian native_encode_expr stored the rhs
			 such that the LSB of it is the LSB of buffer[len - 1].
			 That bit is stored into memory at position
			 offset2 + size2 - 1, i.e. in byte
			 base + (offset2 + size2 - 1) / BITS_PER_UNIT.
			 E.g. for offset2 1 and size2 14, rhs -1 and memory
			 previously cleared that is:
			 0        1
			 01111111|11111110
			 Now, if we want to extract offset 2 and size 12 from
			 it using native_interpret_expr (which actually works
			 for integral bitfield types in terms of byte size of
			 the mode), the native_encode_expr stored the value
			 into buffer as
			 XX111111|11111111
			 and returned len 2 (the X bits are outside of
			 precision).
			 Let sz be maxsize / BITS_PER_UNIT if not extracting
			 a bitfield, and GET_MODE_SIZE otherwise.
			 We need to align the LSB of the value we want to
			 extract as the LSB of buf[sz - 1].
			 The LSB from memory we need to read is at position
			 offset + maxsize - 1.  */
		      HOST_WIDE_INT sz = maxsizei / BITS_PER_UNIT;
		      if (INTEGRAL_TYPE_P (type))
			sz = GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (type));
		      amnt = ((unsigned HOST_WIDE_INT) offset2i + size2i
			      - offseti - maxsizei) % BITS_PER_UNIT;
		      if (amnt)
			shift_bytes_in_array_right (buffer, len, amnt);
		      amnt = ((unsigned HOST_WIDE_INT) offset2i + size2i
			      - offseti - maxsizei - amnt) / BITS_PER_UNIT;
		      if ((unsigned HOST_WIDE_INT) sz + amnt > (unsigned) len)
			len = 0;
		      else
			{
			  buf = buffer + len - sz - amnt;
			  len -= (buf - buffer);
			}
		    }
		  else
		    {
		      amnt = ((unsigned HOST_WIDE_INT) offset2i
			      - offseti) % BITS_PER_UNIT;
		      if (amnt)
			{
			  buffer[len] = 0;
			  shift_bytes_in_array_left (buffer, len + 1, amnt);
			  buf = buffer + 1;
			}
		    }
		  tree val = native_interpret_expr (type, buf, len);
		  /* If we chop off bits because the types precision doesn't
		     match the memory access size this is ok when optimizing
		     reads but not when called from the DSE code during
		     elimination.  */
		  if (val
		      && type != vr->type)
		    {
		      if (! int_fits_type_p (val, vr->type))
			val = NULL_TREE;
		      else
			val = fold_convert (vr->type, val);
		    }

		  if (val)
		    return data->finish (ao_ref_alias_set (&lhs_ref),
					 ao_ref_base_alias_set (&lhs_ref), val);
		}
	    }
	  else if (ranges_known_overlap_p (offseti, maxsizei, offset2i,
					   size2i))
	    {
	      pd_data pd;
	      tree rhs = gimple_assign_rhs1 (def_stmt);
	      if (TREE_CODE (rhs) == SSA_NAME)
		rhs = SSA_VAL (rhs);
	      pd.rhs = rhs;
	      pd.offset = offset2i;
	      pd.size = size2i;
	      return data->push_partial_def (pd, ao_ref_alias_set (&lhs_ref),
					     ao_ref_base_alias_set (&lhs_ref),
					     offseti, maxsizei);
	    }
	}
    }

  /* 4) Assignment from an SSA name which definition we may be able
     to access pieces from or we can combine to a larger entity.  */
  else if (known_eq (ref->size, maxsize)
	   && is_gimple_reg_type (vr->type)
	   && !contains_storage_order_barrier_p (vr->operands)
	   && gimple_assign_single_p (def_stmt)
	   && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME)
    {
      tree lhs = gimple_assign_lhs (def_stmt);
      tree base2;
      poly_int64 offset2, size2, maxsize2;
      HOST_WIDE_INT offset2i, size2i, offseti;
      bool reverse;
      gcc_assert (lhs_ref_ok);
      base2 = ao_ref_base (&lhs_ref);
      offset2 = lhs_ref.offset;
      size2 = lhs_ref.size;
      maxsize2 = lhs_ref.max_size;
      reverse = reverse_storage_order_for_component_p (lhs);
      tree def_rhs = gimple_assign_rhs1 (def_stmt);
      if (!reverse
	  && !storage_order_barrier_p (lhs)
	  && known_size_p (maxsize2)
	  && known_eq (maxsize2, size2)
	  && adjust_offsets_for_equal_base_address (base, &offset,
						    base2, &offset2))
	{
	  if (data->partial_defs.is_empty ()
	      && known_subrange_p (offset, maxsize, offset2, size2)
	      /* ???  We can't handle bitfield precision extracts without
		 either using an alternate type for the BIT_FIELD_REF and
		 then doing a conversion or possibly adjusting the offset
		 according to endianness.  */
	      && (! INTEGRAL_TYPE_P (vr->type)
		  || known_eq (ref->size, TYPE_PRECISION (vr->type)))
	      && multiple_p (ref->size, BITS_PER_UNIT))
	    {
	      tree val = NULL_TREE;
	      if (! INTEGRAL_TYPE_P (TREE_TYPE (def_rhs))
		  || type_has_mode_precision_p (TREE_TYPE (def_rhs)))
		{
		  gimple_match_op op (gimple_match_cond::UNCOND,
				      BIT_FIELD_REF, vr->type,
				      SSA_VAL (def_rhs),
				      bitsize_int (ref->size),
				      bitsize_int (offset - offset2));
		  val = vn_nary_build_or_lookup (&op);
		}
	      else if (known_eq (ref->size, size2))
		{
		  gimple_match_op op (gimple_match_cond::UNCOND,
				      VIEW_CONVERT_EXPR, vr->type,
				      SSA_VAL (def_rhs));
		  val = vn_nary_build_or_lookup (&op);
		}
	      if (val
		  && (TREE_CODE (val) != SSA_NAME
		      || ! SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val)))
		return data->finish (ao_ref_alias_set (&lhs_ref),
				     ao_ref_base_alias_set (&lhs_ref), val);
	    }
	  else if (maxsize.is_constant (&maxsizei)
		   && offset.is_constant (&offseti)
		   && offset2.is_constant (&offset2i)
		   && size2.is_constant (&size2i)
		   && ranges_known_overlap_p (offset, maxsize, offset2, size2))
	    {
	      pd_data pd;
	      pd.rhs = SSA_VAL (def_rhs);
	      pd.offset = offset2i;
	      pd.size = size2i;
	      return data->push_partial_def (pd, ao_ref_alias_set (&lhs_ref),
					     ao_ref_base_alias_set (&lhs_ref),
					     offseti, maxsizei);
	    }
	}
    }

  /* 5) For aggregate copies translate the reference through them if
     the copy kills ref.  */
  else if (data->vn_walk_kind == VN_WALKREWRITE
	   && gimple_assign_single_p (def_stmt)
	   && (DECL_P (gimple_assign_rhs1 (def_stmt))
	       || TREE_CODE (gimple_assign_rhs1 (def_stmt)) == MEM_REF
	       || handled_component_p (gimple_assign_rhs1 (def_stmt))))
    {
      tree base2;
      int i, j, k;
      auto_vec<vn_reference_op_s> rhs;
      vn_reference_op_t vro;
      ao_ref r;

      gcc_assert (lhs_ref_ok);

      /* See if the assignment kills REF.  */
      base2 = ao_ref_base (&lhs_ref);
      if (!lhs_ref.max_size_known_p ()
	  || (base != base2
	      && (TREE_CODE (base) != MEM_REF
		  || TREE_CODE (base2) != MEM_REF
		  || TREE_OPERAND (base, 0) != TREE_OPERAND (base2, 0)
		  || !tree_int_cst_equal (TREE_OPERAND (base, 1),
					  TREE_OPERAND (base2, 1))))
	  || !stmt_kills_ref_p (def_stmt, ref))
	return (void *)-1;

      /* Find the common base of ref and the lhs.  lhs_ops already
         contains valueized operands for the lhs.  */
      i = vr->operands.length () - 1;
      j = lhs_ops.length () - 1;
      while (j >= 0 && i >= 0
	     && vn_reference_op_eq (&vr->operands[i], &lhs_ops[j]))
	{
	  i--;
	  j--;
	}

      /* ???  The innermost op should always be a MEM_REF and we already
         checked that the assignment to the lhs kills vr.  Thus for
	 aggregate copies using char[] types the vn_reference_op_eq
	 may fail when comparing types for compatibility.  But we really
	 don't care here - further lookups with the rewritten operands
	 will simply fail if we messed up types too badly.  */
      poly_int64 extra_off = 0;
      if (j == 0 && i >= 0
	  && lhs_ops[0].opcode == MEM_REF
	  && maybe_ne (lhs_ops[0].off, -1))
	{
	  if (known_eq (lhs_ops[0].off, vr->operands[i].off))
	    i--, j--;
	  else if (vr->operands[i].opcode == MEM_REF
		   && maybe_ne (vr->operands[i].off, -1))
	    {
	      extra_off = vr->operands[i].off - lhs_ops[0].off;
	      i--, j--;
	    }
	}

      /* i now points to the first additional op.
	 ???  LHS may not be completely contained in VR, one or more
	 VIEW_CONVERT_EXPRs could be in its way.  We could at least
	 try handling outermost VIEW_CONVERT_EXPRs.  */
      if (j != -1)
	return (void *)-1;

      /* Punt if the additional ops contain a storage order barrier.  */
      for (k = i; k >= 0; k--)
	{
	  vro = &vr->operands[k];
	  if (vro->opcode == VIEW_CONVERT_EXPR && vro->reverse)
	    return (void *)-1;
	}

      /* Now re-write REF to be based on the rhs of the assignment.  */
      tree rhs1 = gimple_assign_rhs1 (def_stmt);
      copy_reference_ops_from_ref (rhs1, &rhs);

      /* Apply an extra offset to the inner MEM_REF of the RHS.  */
      if (maybe_ne (extra_off, 0))
	{
	  if (rhs.length () < 2)
	    return (void *)-1;
	  int ix = rhs.length () - 2;
	  if (rhs[ix].opcode != MEM_REF
	      || known_eq (rhs[ix].off, -1))
	    return (void *)-1;
	  rhs[ix].off += extra_off;
	  rhs[ix].op0 = int_const_binop (PLUS_EXPR, rhs[ix].op0,
					 build_int_cst (TREE_TYPE (rhs[ix].op0),
							extra_off));
	}

      /* Save the operands since we need to use the original ones for
	 the hash entry we use.  */
      if (!data->saved_operands.exists ())
	data->saved_operands = vr->operands.copy ();

      /* We need to pre-pend vr->operands[0..i] to rhs.  */
      vec<vn_reference_op_s> old = vr->operands;
      if (i + 1 + rhs.length () > vr->operands.length ())
	vr->operands.safe_grow (i + 1 + rhs.length ());
      else
	vr->operands.truncate (i + 1 + rhs.length ());
      FOR_EACH_VEC_ELT (rhs, j, vro)
	vr->operands[i + 1 + j] = *vro;
      vr->operands = valueize_refs (vr->operands);
      if (old == shared_lookup_references)
	shared_lookup_references = vr->operands;
      vr->hashcode = vn_reference_compute_hash (vr);

      /* Try folding the new reference to a constant.  */
      tree val = fully_constant_vn_reference_p (vr);
      if (val)
	{
	  if (data->partial_defs.is_empty ())
	    return data->finish (ao_ref_alias_set (&lhs_ref),
				 ao_ref_base_alias_set (&lhs_ref), val);
	  /* This is the only interesting case for partial-def handling
	     coming from targets that like to gimplify init-ctors as
	     aggregate copies from constant data like aarch64 for
	     PR83518.  */
	  if (maxsize.is_constant (&maxsizei) && known_eq (ref->size, maxsize))
	    {
	      pd_data pd;
	      pd.rhs = val;
	      pd.offset = 0;
	      pd.size = maxsizei;
	      return data->push_partial_def (pd, ao_ref_alias_set (&lhs_ref),
					     ao_ref_base_alias_set (&lhs_ref),
					     0, maxsizei);
	    }
	}

      /* Continuing with partial defs isn't easily possible here, we
         have to find a full def from further lookups from here.  Probably
	 not worth the special-casing everywhere.  */
      if (!data->partial_defs.is_empty ())
	return (void *)-1;

      /* Adjust *ref from the new operands.  */
      ao_ref rhs1_ref;
      ao_ref_init (&rhs1_ref, rhs1);
      if (!ao_ref_init_from_vn_reference (&r, ao_ref_alias_set (&rhs1_ref),
					  ao_ref_base_alias_set (&rhs1_ref),
					  vr->type, vr->operands))
	return (void *)-1;
      /* This can happen with bitfields.  */
      if (maybe_ne (ref->size, r.size))
	return (void *)-1;
      *ref = r;

      /* Do not update last seen VUSE after translating.  */
      data->last_vuse_ptr = NULL;
      /* Invalidate the original access path since it now contains
         the wrong base.  */
      data->orig_ref.ref = NULL_TREE;
      /* Use the alias-set of this LHS for recording an eventual result.  */
      if (data->first_set == -2)
	{
	  data->first_set = ao_ref_alias_set (&lhs_ref);
	  data->first_base_set = ao_ref_base_alias_set (&lhs_ref);
	}

      /* Keep looking for the adjusted *REF / VR pair.  */
      return NULL;
    }

  /* 6) For memcpy copies translate the reference through them if
     the copy kills ref.  */
  else if (data->vn_walk_kind == VN_WALKREWRITE
	   && is_gimple_reg_type (vr->type)
	   /* ???  Handle BCOPY as well.  */
	   && (gimple_call_builtin_p (def_stmt, BUILT_IN_MEMCPY)
	       || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMCPY_CHK)
	       || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMPCPY)
	       || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMPCPY_CHK)
	       || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMMOVE)
	       || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMMOVE_CHK))
	   && (TREE_CODE (gimple_call_arg (def_stmt, 0)) == ADDR_EXPR
	       || TREE_CODE (gimple_call_arg (def_stmt, 0)) == SSA_NAME)
	   && (TREE_CODE (gimple_call_arg (def_stmt, 1)) == ADDR_EXPR
	       || TREE_CODE (gimple_call_arg (def_stmt, 1)) == SSA_NAME)
	   && (poly_int_tree_p (gimple_call_arg (def_stmt, 2), &copy_size)
	       || (TREE_CODE (gimple_call_arg (def_stmt, 2)) == SSA_NAME
		   && poly_int_tree_p (SSA_VAL (gimple_call_arg (def_stmt, 2)),
				       &copy_size)))
	   /* Handling this is more complicated, give up for now.  */
	   && data->partial_defs.is_empty ())
    {
      tree lhs, rhs;
      ao_ref r;
      poly_int64 rhs_offset, lhs_offset;
      vn_reference_op_s op;
      poly_uint64 mem_offset;
      poly_int64 at, byte_maxsize;

      /* Only handle non-variable, addressable refs.  */
      if (maybe_ne (ref->size, maxsize)
	  || !multiple_p (offset, BITS_PER_UNIT, &at)
	  || !multiple_p (maxsize, BITS_PER_UNIT, &byte_maxsize))
	return (void *)-1;

      /* Extract a pointer base and an offset for the destination.  */
      lhs = gimple_call_arg (def_stmt, 0);
      lhs_offset = 0;
      if (TREE_CODE (lhs) == SSA_NAME)
	{
	  lhs = vn_valueize (lhs);
	  if (TREE_CODE (lhs) == SSA_NAME)
	    {
	      gimple *def_stmt = SSA_NAME_DEF_STMT (lhs);
	      if (gimple_assign_single_p (def_stmt)
		  && gimple_assign_rhs_code (def_stmt) == ADDR_EXPR)
		lhs = gimple_assign_rhs1 (def_stmt);
	    }
	}
      if (TREE_CODE (lhs) == ADDR_EXPR)
	{
	  tree tem = get_addr_base_and_unit_offset (TREE_OPERAND (lhs, 0),
						    &lhs_offset);
	  if (!tem)
	    return (void *)-1;
	  if (TREE_CODE (tem) == MEM_REF
	      && poly_int_tree_p (TREE_OPERAND (tem, 1), &mem_offset))
	    {
	      lhs = TREE_OPERAND (tem, 0);
	      if (TREE_CODE (lhs) == SSA_NAME)
		lhs = vn_valueize (lhs);
	      lhs_offset += mem_offset;
	    }
	  else if (DECL_P (tem))
	    lhs = build_fold_addr_expr (tem);
	  else
	    return (void *)-1;
	}
      if (TREE_CODE (lhs) != SSA_NAME
	  && TREE_CODE (lhs) != ADDR_EXPR)
	return (void *)-1;

      /* Extract a pointer base and an offset for the source.  */
      rhs = gimple_call_arg (def_stmt, 1);
      rhs_offset = 0;
      if (TREE_CODE (rhs) == SSA_NAME)
	rhs = vn_valueize (rhs);
      if (TREE_CODE (rhs) == ADDR_EXPR)
	{
	  tree tem = get_addr_base_and_unit_offset (TREE_OPERAND (rhs, 0),
						    &rhs_offset);
	  if (!tem)
	    return (void *)-1;
	  if (TREE_CODE (tem) == MEM_REF
	      && poly_int_tree_p (TREE_OPERAND (tem, 1), &mem_offset))
	    {
	      rhs = TREE_OPERAND (tem, 0);
	      rhs_offset += mem_offset;
	    }
	  else if (DECL_P (tem)
		   || TREE_CODE (tem) == STRING_CST)
	    rhs = build_fold_addr_expr (tem);
	  else
	    return (void *)-1;
	}
      if (TREE_CODE (rhs) == SSA_NAME)
	rhs = SSA_VAL (rhs);
      else if (TREE_CODE (rhs) != ADDR_EXPR)
	return (void *)-1;

      /* The bases of the destination and the references have to agree.  */
      if (TREE_CODE (base) == MEM_REF)
	{
	  if (TREE_OPERAND (base, 0) != lhs
	      || !poly_int_tree_p (TREE_OPERAND (base, 1), &mem_offset))
	    return (void *) -1;
	  at += mem_offset;
	}
      else if (!DECL_P (base)
	       || TREE_CODE (lhs) != ADDR_EXPR
	       || TREE_OPERAND (lhs, 0) != base)
	return (void *)-1;

      /* If the access is completely outside of the memcpy destination
	 area there is no aliasing.  */
      if (!ranges_maybe_overlap_p (lhs_offset, copy_size, at, byte_maxsize))
	return NULL;
      /* And the access has to be contained within the memcpy destination.  */
      if (!known_subrange_p (at, byte_maxsize, lhs_offset, copy_size))
	return (void *)-1;

      /* Save the operands since we need to use the original ones for
	 the hash entry we use.  */
      if (!data->saved_operands.exists ())
	data->saved_operands = vr->operands.copy ();

      /* Make room for 2 operands in the new reference.  */
      if (vr->operands.length () < 2)
	{
	  vec<vn_reference_op_s> old = vr->operands;
	  vr->operands.safe_grow_cleared (2);
	  if (old == shared_lookup_references)
	    shared_lookup_references = vr->operands;
	}
      else
	vr->operands.truncate (2);

      /* The looked-through reference is a simple MEM_REF.  */
      memset (&op, 0, sizeof (op));
      op.type = vr->type;
      op.opcode = MEM_REF;
      op.op0 = build_int_cst (ptr_type_node, at - lhs_offset + rhs_offset);
      op.off = at - lhs_offset + rhs_offset;
      vr->operands[0] = op;
      op.type = TREE_TYPE (rhs);
      op.opcode = TREE_CODE (rhs);
      op.op0 = rhs;
      op.off = -1;
      vr->operands[1] = op;
      vr->hashcode = vn_reference_compute_hash (vr);

      /* Try folding the new reference to a constant.  */
      tree val = fully_constant_vn_reference_p (vr);
      if (val)
	return data->finish (0, 0, val);

      /* Adjust *ref from the new operands.  */
      if (!ao_ref_init_from_vn_reference (&r, 0, 0, vr->type, vr->operands))
	return (void *)-1;
      /* This can happen with bitfields.  */
      if (maybe_ne (ref->size, r.size))
	return (void *)-1;
      *ref = r;

      /* Do not update last seen VUSE after translating.  */
      data->last_vuse_ptr = NULL;
      /* Invalidate the original access path since it now contains
         the wrong base.  */
      data->orig_ref.ref = NULL_TREE;
      /* Use the alias-set of this stmt for recording an eventual result.  */
      if (data->first_set == -2)
	{
	  data->first_set = 0;
	  data->first_base_set = 0;
	}

      /* Keep looking for the adjusted *REF / VR pair.  */
      return NULL;
    }

  /* Bail out and stop walking.  */
  return (void *)-1;
}

/* Return a reference op vector from OP that can be used for
   vn_reference_lookup_pieces.  The caller is responsible for releasing
   the vector.  */

vec<vn_reference_op_s>
vn_reference_operands_for_lookup (tree op)
{
  bool valueized;
  return valueize_shared_reference_ops_from_ref (op, &valueized).copy ();
}

/* Lookup a reference operation by it's parts, in the current hash table.
   Returns the resulting value number if it exists in the hash table,
   NULL_TREE otherwise.  VNRESULT will be filled in with the actual
   vn_reference_t stored in the hashtable if something is found.  */

tree
vn_reference_lookup_pieces (tree vuse, alias_set_type set,
			    alias_set_type base_set, tree type,
			    vec<vn_reference_op_s> operands,
			    vn_reference_t *vnresult, vn_lookup_kind kind)
{
  struct vn_reference_s vr1;
  vn_reference_t tmp;
  tree cst;

  if (!vnresult)
    vnresult = &tmp;
  *vnresult = NULL;

  vr1.vuse = vuse_ssa_val (vuse);
  shared_lookup_references.truncate (0);
  shared_lookup_references.safe_grow (operands.length ());
  memcpy (shared_lookup_references.address (),
	  operands.address (),
	  sizeof (vn_reference_op_s)
	  * operands.length ());
  vr1.operands = operands = shared_lookup_references
    = valueize_refs (shared_lookup_references);
  vr1.type = type;
  vr1.set = set;
  vr1.base_set = base_set;
  vr1.hashcode = vn_reference_compute_hash (&vr1);
  if ((cst = fully_constant_vn_reference_p (&vr1)))
    return cst;

  vn_reference_lookup_1 (&vr1, vnresult);
  if (!*vnresult
      && kind != VN_NOWALK
      && vr1.vuse)
    {
      ao_ref r;
      unsigned limit = param_sccvn_max_alias_queries_per_access;
      vn_walk_cb_data data (&vr1, NULL_TREE, NULL, kind, true, NULL_TREE);
      if (ao_ref_init_from_vn_reference (&r, set, base_set, type,
					 vr1.operands))
	*vnresult
	  = ((vn_reference_t)
	     walk_non_aliased_vuses (&r, vr1.vuse, true, vn_reference_lookup_2,
				     vn_reference_lookup_3, vuse_valueize,
				     limit, &data));
      gcc_checking_assert (vr1.operands == shared_lookup_references);
    }

  if (*vnresult)
     return (*vnresult)->result;

  return NULL_TREE;
}

/* Lookup OP in the current hash table, and return the resulting value
   number if it exists in the hash table.  Return NULL_TREE if it does
   not exist in the hash table or if the result field of the structure
   was NULL..  VNRESULT will be filled in with the vn_reference_t
   stored in the hashtable if one exists.  When TBAA_P is false assume
   we are looking up a store and treat it as having alias-set zero.
   *LAST_VUSE_PTR will be updated with the VUSE the value lookup succeeded.
   MASK is either NULL_TREE, or can be an INTEGER_CST if the result of the
   load is bitwise anded with MASK and so we are only interested in a subset
   of the bits and can ignore if the other bits are uninitialized or
   not initialized with constants.  */

tree
vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind,
		     vn_reference_t *vnresult, bool tbaa_p,
		     tree *last_vuse_ptr, tree mask)
{
  vec<vn_reference_op_s> operands;
  struct vn_reference_s vr1;
  bool valuezied_anything;

  if (vnresult)
    *vnresult = NULL;

  vr1.vuse = vuse_ssa_val (vuse);
  vr1.operands = operands
    = valueize_shared_reference_ops_from_ref (op, &valuezied_anything);
  vr1.type = TREE_TYPE (op);
  ao_ref op_ref;
  ao_ref_init (&op_ref, op);
  vr1.set = ao_ref_alias_set (&op_ref);
  vr1.base_set = ao_ref_base_alias_set (&op_ref);
  vr1.hashcode = vn_reference_compute_hash (&vr1);
  if (mask == NULL_TREE)
    if (tree cst = fully_constant_vn_reference_p (&vr1))
      return cst;

  if (kind != VN_NOWALK && vr1.vuse)
    {
      vn_reference_t wvnresult;
      ao_ref r;
      unsigned limit = param_sccvn_max_alias_queries_per_access;
      /* Make sure to use a valueized reference if we valueized anything.
         Otherwise preserve the full reference for advanced TBAA.  */
      if (!valuezied_anything
	  || !ao_ref_init_from_vn_reference (&r, vr1.set, vr1.base_set,
					     vr1.type, vr1.operands))
	ao_ref_init (&r, op);
      vn_walk_cb_data data (&vr1, r.ref ? NULL_TREE : op,
			    last_vuse_ptr, kind, tbaa_p, mask);

      wvnresult
	= ((vn_reference_t)
	   walk_non_aliased_vuses (&r, vr1.vuse, tbaa_p, vn_reference_lookup_2,
				   vn_reference_lookup_3, vuse_valueize, limit,
				   &data));
      gcc_checking_assert (vr1.operands == shared_lookup_references);
      if (wvnresult)
	{
	  gcc_assert (mask == NULL_TREE);
	  if (vnresult)
	    *vnresult = wvnresult;
	  return wvnresult->result;
	}
      else if (mask)
	return data.masked_result;

      return NULL_TREE;
    }

  if (last_vuse_ptr)
    *last_vuse_ptr = vr1.vuse;
  if (mask)
    return NULL_TREE;
  return vn_reference_lookup_1 (&vr1, vnresult);
}

/* Lookup CALL in the current hash table and return the entry in
   *VNRESULT if found.  Populates *VR for the hashtable lookup.  */

void
vn_reference_lookup_call (gcall *call, vn_reference_t *vnresult,
			  vn_reference_t vr)
{
  if (vnresult)
    *vnresult = NULL;

  tree vuse = gimple_vuse (call);

  vr->vuse = vuse ? SSA_VAL (vuse) : NULL_TREE;
  vr->operands = valueize_shared_reference_ops_from_call (call);
  vr->type = gimple_expr_type (call);
  vr->set = 0;
  vr->base_set = 0;
  vr->hashcode = vn_reference_compute_hash (vr);
  vn_reference_lookup_1 (vr, vnresult);
}

/* Insert OP into the current hash table with a value number of RESULT.  */

static void 
vn_reference_insert (tree op, tree result, tree vuse, tree vdef)
{
  vn_reference_s **slot;
  vn_reference_t vr1;
  bool tem;

  vr1 = XOBNEW (&vn_tables_obstack, vn_reference_s);
  if (TREE_CODE (result) == SSA_NAME)
    vr1->value_id = VN_INFO (result)->value_id;
  else
    vr1->value_id = get_or_alloc_constant_value_id (result);
  vr1->vuse = vuse_ssa_val (vuse);
  vr1->operands = valueize_shared_reference_ops_from_ref (op, &tem).copy ();
  vr1->type = TREE_TYPE (op);
  ao_ref op_ref;
  ao_ref_init (&op_ref, op);
  vr1->set = ao_ref_alias_set (&op_ref);
  vr1->base_set = ao_ref_base_alias_set (&op_ref);
  vr1->hashcode = vn_reference_compute_hash (vr1);
  vr1->result = TREE_CODE (result) == SSA_NAME ? SSA_VAL (result) : result;
  vr1->result_vdef = vdef;

  slot = valid_info->references->find_slot_with_hash (vr1, vr1->hashcode,
						      INSERT);

  /* Because IL walking on reference lookup can end up visiting
     a def that is only to be visited later in iteration order
     when we are about to make an irreducible region reducible
     the def can be effectively processed and its ref being inserted
     by vn_reference_lookup_3 already.  So we cannot assert (!*slot)
     but save a lookup if we deal with already inserted refs here.  */
  if (*slot)
    {
      /* We cannot assert that we have the same value either because
         when disentangling an irreducible region we may end up visiting
	 a use before the corresponding def.  That's a missed optimization
	 only though.  See gcc.dg/tree-ssa/pr87126.c for example.  */
      if (dump_file && (dump_flags & TDF_DETAILS)
	  && !operand_equal_p ((*slot)->result, vr1->result, 0))
	{
	  fprintf (dump_file, "Keeping old value ");
	  print_generic_expr (dump_file, (*slot)->result);
	  fprintf (dump_file, " because of collision\n");
	}
      free_reference (vr1);
      obstack_free (&vn_tables_obstack, vr1);
      return;
    }

  *slot = vr1;
  vr1->next = last_inserted_ref;
  last_inserted_ref = vr1;
}

/* Insert a reference by it's pieces into the current hash table with
   a value number of RESULT.  Return the resulting reference
   structure we created.  */

vn_reference_t
vn_reference_insert_pieces (tree vuse, alias_set_type set,
			    alias_set_type base_set, tree type,
			    vec<vn_reference_op_s> operands,
			    tree result, unsigned int value_id)

{
  vn_reference_s **slot;
  vn_reference_t vr1;

  vr1 = XOBNEW (&vn_tables_obstack, vn_reference_s);
  vr1->value_id = value_id;
  vr1->vuse = vuse_ssa_val (vuse);
  vr1->operands = valueize_refs (operands);
  vr1->type = type;
  vr1->set = set;
  vr1->base_set = base_set;
  vr1->hashcode = vn_reference_compute_hash (vr1);
  if (result && TREE_CODE (result) == SSA_NAME)
    result = SSA_VAL (result);
  vr1->result = result;

  slot = valid_info->references->find_slot_with_hash (vr1, vr1->hashcode,
						      INSERT);

  /* At this point we should have all the things inserted that we have
     seen before, and we should never try inserting something that
     already exists.  */
  gcc_assert (!*slot);

  *slot = vr1;
  vr1->next = last_inserted_ref;
  last_inserted_ref = vr1;
  return vr1;
}

/* Compute and return the hash value for nary operation VBO1.  */

static hashval_t
vn_nary_op_compute_hash (const vn_nary_op_t vno1)
{
  inchash::hash hstate;
  unsigned i;

  for (i = 0; i < vno1->length; ++i)
    if (TREE_CODE (vno1->op[i]) == SSA_NAME)
      vno1->op[i] = SSA_VAL (vno1->op[i]);

  if (((vno1->length == 2
	&& commutative_tree_code (vno1->opcode))
       || (vno1->length == 3
	   && commutative_ternary_tree_code (vno1->opcode)))
      && tree_swap_operands_p (vno1->op[0], vno1->op[1]))
    std::swap (vno1->op[0], vno1->op[1]);
  else if (TREE_CODE_CLASS (vno1->opcode) == tcc_comparison
	   && tree_swap_operands_p (vno1->op[0], vno1->op[1]))
    {
      std::swap (vno1->op[0], vno1->op[1]);
      vno1->opcode = swap_tree_comparison  (vno1->opcode);
    }

  hstate.add_int (vno1->opcode);
  for (i = 0; i < vno1->length; ++i)
    inchash::add_expr (vno1->op[i], hstate);

  return hstate.end ();
}

/* Compare nary operations VNO1 and VNO2 and return true if they are
   equivalent.  */

bool
vn_nary_op_eq (const_vn_nary_op_t const vno1, const_vn_nary_op_t const vno2)
{
  unsigned i;

  if (vno1->hashcode != vno2->hashcode)
    return false;

  if (vno1->length != vno2->length)
    return false;

  if (vno1->opcode != vno2->opcode
      || !types_compatible_p (vno1->type, vno2->type))
    return false;

  for (i = 0; i < vno1->length; ++i)
    if (!expressions_equal_p (vno1->op[i], vno2->op[i]))
      return false;

  /* BIT_INSERT_EXPR has an implict operand as the type precision
     of op1.  Need to check to make sure they are the same.  */
  if (vno1->opcode == BIT_INSERT_EXPR
      && TREE_CODE (vno1->op[1]) == INTEGER_CST
      && TYPE_PRECISION (TREE_TYPE (vno1->op[1]))
	 != TYPE_PRECISION (TREE_TYPE (vno2->op[1])))
    return false;

  return true;
}

/* Initialize VNO from the pieces provided.  */

static void
init_vn_nary_op_from_pieces (vn_nary_op_t vno, unsigned int length,
			     enum tree_code code, tree type, tree *ops)
{
  vno->opcode = code;
  vno->length = length;
  vno->type = type;
  memcpy (&vno->op[0], ops, sizeof (tree) * length);
}

/* Return the number of operands for a vn_nary ops structure from STMT.  */

static unsigned int
vn_nary_length_from_stmt (gimple *stmt)
{
  switch (gimple_assign_rhs_code (stmt))
    {
    case REALPART_EXPR:
    case IMAGPART_EXPR:
    case VIEW_CONVERT_EXPR:
      return 1;

    case BIT_FIELD_REF:
      return 3;

    case CONSTRUCTOR:
      return CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt));

    default:
      return gimple_num_ops (stmt) - 1;
    }
}

/* Initialize VNO from STMT.  */

static void
init_vn_nary_op_from_stmt (vn_nary_op_t vno, gimple *stmt)
{
  unsigned i;

  vno->opcode = gimple_assign_rhs_code (stmt);
  vno->type = gimple_expr_type (stmt);
  switch (vno->opcode)
    {
    case REALPART_EXPR:
    case IMAGPART_EXPR:
    case VIEW_CONVERT_EXPR:
      vno->length = 1;
      vno->op[0] = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
      break;

    case BIT_FIELD_REF:
      vno->length = 3;
      vno->op[0] = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
      vno->op[1] = TREE_OPERAND (gimple_assign_rhs1 (stmt), 1);
      vno->op[2] = TREE_OPERAND (gimple_assign_rhs1 (stmt), 2);
      break;

    case CONSTRUCTOR:
      vno->length = CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt));
      for (i = 0; i < vno->length; ++i)
	vno->op[i] = CONSTRUCTOR_ELT (gimple_assign_rhs1 (stmt), i)->value;
      break;

    default:
      gcc_checking_assert (!gimple_assign_single_p (stmt));
      vno->length = gimple_num_ops (stmt) - 1;
      for (i = 0; i < vno->length; ++i)
	vno->op[i] = gimple_op (stmt, i + 1);
    }
}

/* Compute the hashcode for VNO and look for it in the hash table;
   return the resulting value number if it exists in the hash table.
   Return NULL_TREE if it does not exist in the hash table or if the
   result field of the operation is NULL.  VNRESULT will contain the
   vn_nary_op_t from the hashtable if it exists.  */

static tree
vn_nary_op_lookup_1 (vn_nary_op_t vno, vn_nary_op_t *vnresult)
{
  vn_nary_op_s **slot;

  if (vnresult)
    *vnresult = NULL;

  vno->hashcode = vn_nary_op_compute_hash (vno);
  slot = valid_info->nary->find_slot_with_hash (vno, vno->hashcode, NO_INSERT);
  if (!slot)
    return NULL_TREE;
  if (vnresult)
    *vnresult = *slot;
  return (*slot)->predicated_values ? NULL_TREE : (*slot)->u.result;
}

/* Lookup a n-ary operation by its pieces and return the resulting value
   number if it exists in the hash table.  Return NULL_TREE if it does
   not exist in the hash table or if the result field of the operation
   is NULL. VNRESULT will contain the vn_nary_op_t from the hashtable
   if it exists.  */

tree
vn_nary_op_lookup_pieces (unsigned int length, enum tree_code code,
			  tree type, tree *ops, vn_nary_op_t *vnresult)
{
  vn_nary_op_t vno1 = XALLOCAVAR (struct vn_nary_op_s,
				  sizeof_vn_nary_op (length));
  init_vn_nary_op_from_pieces (vno1, length, code, type, ops);
  return vn_nary_op_lookup_1 (vno1, vnresult);
}

/* Lookup the rhs of STMT in the current hash table, and return the resulting
   value number if it exists in the hash table.  Return NULL_TREE if
   it does not exist in the hash table.  VNRESULT will contain the
   vn_nary_op_t from the hashtable if it exists.  */

tree
vn_nary_op_lookup_stmt (gimple *stmt, vn_nary_op_t *vnresult)
{
  vn_nary_op_t vno1
    = XALLOCAVAR (struct vn_nary_op_s,
		  sizeof_vn_nary_op (vn_nary_length_from_stmt (stmt)));
  init_vn_nary_op_from_stmt (vno1, stmt);
  return vn_nary_op_lookup_1 (vno1, vnresult);
}

/* Allocate a vn_nary_op_t with LENGTH operands on STACK.  */

static vn_nary_op_t
alloc_vn_nary_op_noinit (unsigned int length, struct obstack *stack)
{
  return (vn_nary_op_t) obstack_alloc (stack, sizeof_vn_nary_op (length));
}

/* Allocate and initialize a vn_nary_op_t on CURRENT_INFO's
   obstack.  */

static vn_nary_op_t
alloc_vn_nary_op (unsigned int length, tree result, unsigned int value_id)
{
  vn_nary_op_t vno1 = alloc_vn_nary_op_noinit (length, &vn_tables_obstack);

  vno1->value_id = value_id;
  vno1->length = length;
  vno1->predicated_values = 0;
  vno1->u.result = result;

  return vno1;
}

/* Insert VNO into TABLE.  If COMPUTE_HASH is true, then compute
   VNO->HASHCODE first.  */

static vn_nary_op_t
vn_nary_op_insert_into (vn_nary_op_t vno, vn_nary_op_table_type *table,
			bool compute_hash)
{
  vn_nary_op_s **slot;

  if (compute_hash)
    {
      vno->hashcode = vn_nary_op_compute_hash (vno);
      gcc_assert (! vno->predicated_values
		  || (! vno->u.values->next
		      && vno->u.values->n == 1));
    }

  slot = table->find_slot_with_hash (vno, vno->hashcode, INSERT);
  vno->unwind_to = *slot;
  if (*slot)
    {
      /* Prefer non-predicated values.
         ???  Only if those are constant, otherwise, with constant predicated
	 value, turn them into predicated values with entry-block validity
	 (???  but we always find the first valid result currently).  */
      if ((*slot)->predicated_values
	  && ! vno->predicated_values)
	{
	  /* ???  We cannot remove *slot from the unwind stack list.
	     For the moment we deal with this by skipping not found
	     entries but this isn't ideal ...  */
	  *slot = vno;
	  /* ???  Maintain a stack of states we can unwind in
	     vn_nary_op_s?  But how far do we unwind?  In reality
	     we need to push change records somewhere...  Or not
	     unwind vn_nary_op_s and linking them but instead
	     unwind the results "list", linking that, which also
	     doesn't move on hashtable resize.  */
	  /* We can also have a ->unwind_to recording *slot there.
	     That way we can make u.values a fixed size array with
	     recording the number of entries but of course we then
	     have always N copies for each unwind_to-state.  Or we
             make sure to only ever append and each unwinding will
	     pop off one entry (but how to deal with predicated
	     replaced with non-predicated here?)  */
	  vno->next = last_inserted_nary;
	  last_inserted_nary = vno;
	  return vno;
	}
      else if (vno->predicated_values
	       && ! (*slot)->predicated_values)
	return *slot;
      else if (vno->predicated_values
	       && (*slot)->predicated_values)
	{
	  /* ???  Factor this all into a insert_single_predicated_value
	     routine.  */
	  gcc_assert (!vno->u.values->next && vno->u.values->n == 1);
	  basic_block vno_bb
	    = BASIC_BLOCK_FOR_FN (cfun, vno->u.values->valid_dominated_by_p[0]);
	  vn_pval *nval = vno->u.values;
	  vn_pval **next = &vno->u.values;
	  bool found = false;
	  for (vn_pval *val = (*slot)->u.values; val; val = val->next)
	    {
	      if (expressions_equal_p (val->result, vno->u.values->result))
		{
		  found = true;
		  for (unsigned i = 0; i < val->n; ++i)
		    {
		      basic_block val_bb
			= BASIC_BLOCK_FOR_FN (cfun,
					      val->valid_dominated_by_p[i]);
		      if (dominated_by_p (CDI_DOMINATORS, vno_bb, val_bb))
			/* Value registered with more generic predicate.  */
			return *slot;
		      else if (dominated_by_p (CDI_DOMINATORS, val_bb, vno_bb))
			/* Shouldn't happen, we insert in RPO order.  */
			gcc_unreachable ();
		    }
		  /* Append value.  */
		  *next = (vn_pval *) obstack_alloc (&vn_tables_obstack,
						     sizeof (vn_pval)
						     + val->n * sizeof (int));
		  (*next)->next = NULL;
		  (*next)->result = val->result;
		  (*next)->n = val->n + 1;
		  memcpy ((*next)->valid_dominated_by_p,
			  val->valid_dominated_by_p,
			  val->n * sizeof (int));
		  (*next)->valid_dominated_by_p[val->n] = vno_bb->index;
		  next = &(*next)->next;
		  if (dump_file && (dump_flags & TDF_DETAILS))
		    fprintf (dump_file, "Appending predicate to value.\n");
		  continue;
		}
	      /* Copy other predicated values.  */
	      *next = (vn_pval *) obstack_alloc (&vn_tables_obstack,
						 sizeof (vn_pval)
						 + (val->n-1) * sizeof (int));
	      memcpy (*next, val, sizeof (vn_pval) + (val->n-1) * sizeof (int));
	      (*next)->next = NULL;
	      next = &(*next)->next;
	    }
	  if (!found)
	    *next = nval;

	  *slot = vno;
	  vno->next = last_inserted_nary;
	  last_inserted_nary = vno;
	  return vno;
	}

      /* While we do not want to insert things twice it's awkward to
	 avoid it in the case where visit_nary_op pattern-matches stuff
	 and ends up simplifying the replacement to itself.  We then
	 get two inserts, one from visit_nary_op and one from
	 vn_nary_build_or_lookup.
	 So allow inserts with the same value number.  */
      if ((*slot)->u.result == vno->u.result)
	return *slot;
    }

  /* ???  There's also optimistic vs. previous commited state merging
     that is problematic for the case of unwinding.  */

  /* ???  We should return NULL if we do not use 'vno' and have the
     caller release it.  */
  gcc_assert (!*slot);

  *slot = vno;
  vno->next = last_inserted_nary;
  last_inserted_nary = vno;
  return vno;
}

/* Insert a n-ary operation into the current hash table using it's
   pieces.  Return the vn_nary_op_t structure we created and put in
   the hashtable.  */

vn_nary_op_t
vn_nary_op_insert_pieces (unsigned int length, enum tree_code code,
			  tree type, tree *ops,
			  tree result, unsigned int value_id)
{
  vn_nary_op_t vno1 = alloc_vn_nary_op (length, result, value_id);
  init_vn_nary_op_from_pieces (vno1, length, code, type, ops);
  return vn_nary_op_insert_into (vno1, valid_info->nary, true);
}

static vn_nary_op_t
vn_nary_op_insert_pieces_predicated (unsigned int length, enum tree_code code,
				     tree type, tree *ops,
				     tree result, unsigned int value_id,
				     edge pred_e)
{
  /* ???  Currently tracking BBs.  */
  if (! single_pred_p (pred_e->dest))
    {
      /* Never record for backedges.  */
      if (pred_e->flags & EDGE_DFS_BACK)
	return NULL;
      edge_iterator ei;
      edge e;
      int cnt = 0;
      /* Ignore backedges.  */
      FOR_EACH_EDGE (e, ei, pred_e->dest->preds)
	if (! dominated_by_p (CDI_DOMINATORS, e->src, e->dest))
	  cnt++;
      if (cnt != 1)
	return NULL;
    }
  if (dump_file && (dump_flags & TDF_DETAILS)
      /* ???  Fix dumping, but currently we only get comparisons.  */
      && TREE_CODE_CLASS (code) == tcc_comparison)
    {
      fprintf (dump_file, "Recording on edge %d->%d ", pred_e->src->index,
	       pred_e->dest->index);
      print_generic_expr (dump_file, ops[0], TDF_SLIM);
      fprintf (dump_file, " %s ", get_tree_code_name (code));
      print_generic_expr (dump_file, ops[1], TDF_SLIM);
      fprintf (dump_file, " == %s\n",
	       integer_zerop (result) ? "false" : "true");
    }
  vn_nary_op_t vno1 = alloc_vn_nary_op (length, NULL_TREE, value_id);
  init_vn_nary_op_from_pieces (vno1, length, code, type, ops);
  vno1->predicated_values = 1;
  vno1->u.values = (vn_pval *) obstack_alloc (&vn_tables_obstack,
					      sizeof (vn_pval));
  vno1->u.values->next = NULL;
  vno1->u.values->result = result;
  vno1->u.values->n = 1;
  vno1->u.values->valid_dominated_by_p[0] = pred_e->dest->index;
  return vn_nary_op_insert_into (vno1, valid_info->nary, true);
}

static bool
dominated_by_p_w_unex (basic_block bb1, basic_block bb2);

static tree
vn_nary_op_get_predicated_value (vn_nary_op_t vno, basic_block bb)
{
  if (! vno->predicated_values)
    return vno->u.result;
  for (vn_pval *val = vno->u.values; val; val = val->next)
    for (unsigned i = 0; i < val->n; ++i)
      if (dominated_by_p_w_unex (bb,
			  BASIC_BLOCK_FOR_FN
			    (cfun, val->valid_dominated_by_p[i])))
	return val->result;
  return NULL_TREE;
}

/* Insert the rhs of STMT into the current hash table with a value number of
   RESULT.  */

static vn_nary_op_t
vn_nary_op_insert_stmt (gimple *stmt, tree result)
{
  vn_nary_op_t vno1
    = alloc_vn_nary_op (vn_nary_length_from_stmt (stmt),
			result, VN_INFO (result)->value_id);
  init_vn_nary_op_from_stmt (vno1, stmt);
  return vn_nary_op_insert_into (vno1, valid_info->nary, true);
}

/* Compute a hashcode for PHI operation VP1 and return it.  */

static inline hashval_t
vn_phi_compute_hash (vn_phi_t vp1)
{
  inchash::hash hstate (EDGE_COUNT (vp1->block->preds) > 2
			? vp1->block->index : EDGE_COUNT (vp1->block->preds));
  tree phi1op;
  tree type;
  edge e;
  edge_iterator ei;

  /* If all PHI arguments are constants we need to distinguish
     the PHI node via its type.  */
  type = vp1->type;
  hstate.merge_hash (vn_hash_type (type));

  FOR_EACH_EDGE (e, ei, vp1->block->preds)
    {
      /* Don't hash backedge values they need to be handled as VN_TOP
         for optimistic value-numbering.  */
      if (e->flags & EDGE_DFS_BACK)
	continue;

      phi1op = vp1->phiargs[e->dest_idx];
      if (phi1op == VN_TOP)
	continue;
      inchash::add_expr (phi1op, hstate);
    }

  return hstate.end ();
}


/* Return true if COND1 and COND2 represent the same condition, set
   *INVERTED_P if one needs to be inverted to make it the same as
   the other.  */

static bool
cond_stmts_equal_p (gcond *cond1, tree lhs1, tree rhs1,
		    gcond *cond2, tree lhs2, tree rhs2, bool *inverted_p)
{
  enum tree_code code1 = gimple_cond_code (cond1);
  enum tree_code code2 = gimple_cond_code (cond2);

  *inverted_p = false;
  if (code1 == code2)
    ;
  else if (code1 == swap_tree_comparison (code2))
    std::swap (lhs2, rhs2);
  else if (code1 == invert_tree_comparison (code2, HONOR_NANS (lhs2)))
    *inverted_p = true;
  else if (code1 == invert_tree_comparison
	   	      (swap_tree_comparison (code2), HONOR_NANS (lhs2)))
    {
      std::swap (lhs2, rhs2);
      *inverted_p = true;
    }
  else
    return false;

  return ((expressions_equal_p (lhs1, lhs2)
	   && expressions_equal_p (rhs1, rhs2))
	  || (commutative_tree_code (code1)
	      && expressions_equal_p (lhs1, rhs2)
	      && expressions_equal_p (rhs1, lhs2)));
}

/* Compare two phi entries for equality, ignoring VN_TOP arguments.  */

static int
vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2)
{
  if (vp1->hashcode != vp2->hashcode)
    return false;

  if (vp1->block != vp2->block)
    {
      if (EDGE_COUNT (vp1->block->preds) != EDGE_COUNT (vp2->block->preds))
	return false;

      switch (EDGE_COUNT (vp1->block->preds))
	{
	case 1:
	  /* Single-arg PHIs are just copies.  */
	  break;

	case 2:
	  {
	    /* Rule out backedges into the PHI.  */
	    if (vp1->block->loop_father->header == vp1->block
		|| vp2->block->loop_father->header == vp2->block)
	      return false;

	    /* If the PHI nodes do not have compatible types
	       they are not the same.  */
	    if (!types_compatible_p (vp1->type, vp2->type))
	      return false;

	    basic_block idom1
	      = get_immediate_dominator (CDI_DOMINATORS, vp1->block);
	    basic_block idom2
	      = get_immediate_dominator (CDI_DOMINATORS, vp2->block);
	    /* If the immediate dominator end in switch stmts multiple
	       values may end up in the same PHI arg via intermediate
	       CFG merges.  */
	    if (EDGE_COUNT (idom1->succs) != 2
		|| EDGE_COUNT (idom2->succs) != 2)
	      return false;

	    /* Verify the controlling stmt is the same.  */
	    gcond *last1 = safe_dyn_cast <gcond *> (last_stmt (idom1));
	    gcond *last2 = safe_dyn_cast <gcond *> (last_stmt (idom2));
	    if (! last1 || ! last2)
	      return false;
	    bool inverted_p;
	    if (! cond_stmts_equal_p (last1, vp1->cclhs, vp1->ccrhs,
				      last2, vp2->cclhs, vp2->ccrhs,
				      &inverted_p))
	      return false;

	    /* Get at true/false controlled edges into the PHI.  */
	    edge te1, te2, fe1, fe2;
	    if (! extract_true_false_controlled_edges (idom1, vp1->block,
						       &te1, &fe1)
		|| ! extract_true_false_controlled_edges (idom2, vp2->block,
							  &te2, &fe2))
	      return false;

	    /* Swap edges if the second condition is the inverted of the
	       first.  */
	    if (inverted_p)
	      std::swap (te2, fe2);

	    /* ???  Handle VN_TOP specially.  */
	    if (! expressions_equal_p (vp1->phiargs[te1->dest_idx],
				       vp2->phiargs[te2->dest_idx])
		|| ! expressions_equal_p (vp1->phiargs[fe1->dest_idx],
					  vp2->phiargs[fe2->dest_idx]))
	      return false;

	    return true;
	  }

	default:
	  return false;
	}
    }

  /* If the PHI nodes do not have compatible types
     they are not the same.  */
  if (!types_compatible_p (vp1->type, vp2->type))
    return false;

  /* Any phi in the same block will have it's arguments in the
     same edge order, because of how we store phi nodes.  */
  for (unsigned i = 0; i < EDGE_COUNT (vp1->block->preds); ++i)
    {
      tree phi1op = vp1->phiargs[i];
      tree phi2op = vp2->phiargs[i];
      if (phi1op == VN_TOP || phi2op == VN_TOP)
	continue;
      if (!expressions_equal_p (phi1op, phi2op))
	return false;
    }

  return true;
}

/* Lookup PHI in the current hash table, and return the resulting
   value number if it exists in the hash table.  Return NULL_TREE if
   it does not exist in the hash table. */

static tree
vn_phi_lookup (gimple *phi, bool backedges_varying_p)
{
  vn_phi_s **slot;
  struct vn_phi_s *vp1;
  edge e;
  edge_iterator ei;

  vp1 = XALLOCAVAR (struct vn_phi_s,
		    sizeof (struct vn_phi_s)
		    + (gimple_phi_num_args (phi) - 1) * sizeof (tree));

  /* Canonicalize the SSA_NAME's to their value number.  */
  FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds)
    {
      tree def = PHI_ARG_DEF_FROM_EDGE (phi, e);
      if (TREE_CODE (def) == SSA_NAME
	  && (!backedges_varying_p || !(e->flags & EDGE_DFS_BACK)))
	def = SSA_VAL (def);
      vp1->phiargs[e->dest_idx] = def;
    }
  vp1->type = TREE_TYPE (gimple_phi_result (phi));
  vp1->block = gimple_bb (phi);
  /* Extract values of the controlling condition.  */
  vp1->cclhs = NULL_TREE;
  vp1->ccrhs = NULL_TREE;
  basic_block idom1 = get_immediate_dominator (CDI_DOMINATORS, vp1->block);
  if (EDGE_COUNT (idom1->succs) == 2)
    if (gcond *last1 = safe_dyn_cast <gcond *> (last_stmt (idom1)))
      {
	/* ???  We want to use SSA_VAL here.  But possibly not
	   allow VN_TOP.  */
	vp1->cclhs = vn_valueize (gimple_cond_lhs (last1));
	vp1->ccrhs = vn_valueize (gimple_cond_rhs (last1));
      }
  vp1->hashcode = vn_phi_compute_hash (vp1);
  slot = valid_info->phis->find_slot_with_hash (vp1, vp1->hashcode, NO_INSERT);
  if (!slot)
    return NULL_TREE;
  return (*slot)->result;
}

/* Insert PHI into the current hash table with a value number of
   RESULT.  */

static vn_phi_t
vn_phi_insert (gimple *phi, tree result, bool backedges_varying_p)
{
  vn_phi_s **slot;
  vn_phi_t vp1 = (vn_phi_t) obstack_alloc (&vn_tables_obstack,
					   sizeof (vn_phi_s)
					   + ((gimple_phi_num_args (phi) - 1)
					      * sizeof (tree)));
  edge e;
  edge_iterator ei;

  /* Canonicalize the SSA_NAME's to their value number.  */
  FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds)
    {
      tree def = PHI_ARG_DEF_FROM_EDGE (phi, e);
      if (TREE_CODE (def) == SSA_NAME
	  && (!backedges_varying_p || !(e->flags & EDGE_DFS_BACK)))
	def = SSA_VAL (def);
      vp1->phiargs[e->dest_idx] = def;
    }
  vp1->value_id = VN_INFO (result)->value_id;
  vp1->type = TREE_TYPE (gimple_phi_result (phi));
  vp1->block = gimple_bb (phi);
  /* Extract values of the controlling condition.  */
  vp1->cclhs = NULL_TREE;
  vp1->ccrhs = NULL_TREE;
  basic_block idom1 = get_immediate_dominator (CDI_DOMINATORS, vp1->block);
  if (EDGE_COUNT (idom1->succs) == 2)
    if (gcond *last1 = safe_dyn_cast <gcond *> (last_stmt (idom1)))
      {
	/* ???  We want to use SSA_VAL here.  But possibly not
	   allow VN_TOP.  */
	vp1->cclhs = vn_valueize (gimple_cond_lhs (last1));
	vp1->ccrhs = vn_valueize (gimple_cond_rhs (last1));
      }
  vp1->result = result;
  vp1->hashcode = vn_phi_compute_hash (vp1);

  slot = valid_info->phis->find_slot_with_hash (vp1, vp1->hashcode, INSERT);
  gcc_assert (!*slot);

  *slot = vp1;
  vp1->next = last_inserted_phi;
  last_inserted_phi = vp1;
  return vp1;
}


/* Return true if BB1 is dominated by BB2 taking into account edges
   that are not executable.  */

static bool
dominated_by_p_w_unex (basic_block bb1, basic_block bb2)
{
  edge_iterator ei;
  edge e;

  if (dominated_by_p (CDI_DOMINATORS, bb1, bb2))
    return true;

  /* Before iterating we'd like to know if there exists a
     (executable) path from bb2 to bb1 at all, if not we can
     directly return false.  For now simply iterate once.  */

  /* Iterate to the single executable bb1 predecessor.  */
  if (EDGE_COUNT (bb1->preds) > 1)
    {
      edge prede = NULL;
      FOR_EACH_EDGE (e, ei, bb1->preds)
	if (e->flags & EDGE_EXECUTABLE)
	  {
	    if (prede)
	      {
		prede = NULL;
		break;
	      }
	    prede = e;
	  }
      if (prede)
	{
	  bb1 = prede->src;

	  /* Re-do the dominance check with changed bb1.  */
	  if (dominated_by_p (CDI_DOMINATORS, bb1, bb2))
	    return true;
	}
    }

  /* Iterate to the single executable bb2 successor.  */
  edge succe = NULL;
  FOR_EACH_EDGE (e, ei, bb2->succs)
    if (e->flags & EDGE_EXECUTABLE)
      {
	if (succe)
	  {
	    succe = NULL;
	    break;
	  }
	succe = e;
      }
  if (succe)
    {
      /* Verify the reached block is only reached through succe.
	 If there is only one edge we can spare us the dominator
	 check and iterate directly.  */
      if (EDGE_COUNT (succe->dest->preds) > 1)
	{
	  FOR_EACH_EDGE (e, ei, succe->dest->preds)
	    if (e != succe
		&& (e->flags & EDGE_EXECUTABLE))
	      {
		succe = NULL;
		break;
	      }
	}
      if (succe)
	{
	  bb2 = succe->dest;

	  /* Re-do the dominance check with changed bb2.  */
	  if (dominated_by_p (CDI_DOMINATORS, bb1, bb2))
	    return true;
	}
    }

  /* We could now iterate updating bb1 / bb2.  */
  return false;
}

/* Set the value number of FROM to TO, return true if it has changed
   as a result.  */

static inline bool
set_ssa_val_to (tree from, tree to)
{
  vn_ssa_aux_t from_info = VN_INFO (from);
  tree currval = from_info->valnum; // SSA_VAL (from)
  poly_int64 toff, coff;
  bool curr_undefined = false;
  bool curr_invariant = false;

  /* The only thing we allow as value numbers are ssa_names
     and invariants.  So assert that here.  We don't allow VN_TOP
     as visiting a stmt should produce a value-number other than
     that.
     ???  Still VN_TOP can happen for unreachable code, so force
     it to varying in that case.  Not all code is prepared to
     get VN_TOP on valueization.  */
  if (to == VN_TOP)
    {
      /* ???  When iterating and visiting PHI <undef, backedge-value>
         for the first time we rightfully get VN_TOP and we need to
	 preserve that to optimize for example gcc.dg/tree-ssa/ssa-sccvn-2.c.
	 With SCCVN we were simply lucky we iterated the other PHI
	 cycles first and thus visited the backedge-value DEF.  */
      if (currval == VN_TOP)
	goto set_and_exit;
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "Forcing value number to varying on "
		 "receiving VN_TOP\n");
      to = from;
    }

  gcc_checking_assert (to != NULL_TREE
		       && ((TREE_CODE (to) == SSA_NAME
			    && (to == from || SSA_VAL (to) == to))
			   || is_gimple_min_invariant (to)));

  if (from != to)
    {
      if (currval == from)
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "Not changing value number of ");
	      print_generic_expr (dump_file, from);
	      fprintf (dump_file, " from VARYING to ");
	      print_generic_expr (dump_file, to);
	      fprintf (dump_file, "\n");
	    }
	  return false;
	}
      curr_invariant = is_gimple_min_invariant (currval);
      curr_undefined = (TREE_CODE (currval) == SSA_NAME
			&& ssa_undefined_value_p (currval, false));
      if (currval != VN_TOP
	  && !curr_invariant
	  && !curr_undefined
	  && is_gimple_min_invariant (to))
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "Forcing VARYING instead of changing "
		       "value number of ");
	      print_generic_expr (dump_file, from);
	      fprintf (dump_file, " from ");
	      print_generic_expr (dump_file, currval);
	      fprintf (dump_file, " (non-constant) to ");
	      print_generic_expr (dump_file, to);
	      fprintf (dump_file, " (constant)\n");
	    }
	  to = from;
	}
      else if (currval != VN_TOP
	       && !curr_undefined
	       && TREE_CODE (to) == SSA_NAME
	       && ssa_undefined_value_p (to, false))
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "Forcing VARYING instead of changing "
		       "value number of ");
	      print_generic_expr (dump_file, from);
	      fprintf (dump_file, " from ");
	      print_generic_expr (dump_file, currval);
	      fprintf (dump_file, " (non-undefined) to ");
	      print_generic_expr (dump_file, to);
	      fprintf (dump_file, " (undefined)\n");
	    }
	  to = from;
	}
      else if (TREE_CODE (to) == SSA_NAME
	       && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (to))
	to = from;
    }

set_and_exit:
  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Setting value number of ");
      print_generic_expr (dump_file, from);
      fprintf (dump_file, " to ");
      print_generic_expr (dump_file, to);
    }

  if (currval != to
      && !operand_equal_p (currval, to, 0)
      /* Different undefined SSA names are not actually different.  See
         PR82320 for a testcase were we'd otherwise not terminate iteration.  */
      && !(curr_undefined
	   && TREE_CODE (to) == SSA_NAME
	   && ssa_undefined_value_p (to, false))
      /* ???  For addresses involving volatile objects or types operand_equal_p
         does not reliably detect ADDR_EXPRs as equal.  We know we are only
	 getting invariant gimple addresses here, so can use
	 get_addr_base_and_unit_offset to do this comparison.  */
      && !(TREE_CODE (currval) == ADDR_EXPR
	   && TREE_CODE (to) == ADDR_EXPR
	   && (get_addr_base_and_unit_offset (TREE_OPERAND (currval, 0), &coff)
	       == get_addr_base_and_unit_offset (TREE_OPERAND (to, 0), &toff))
	   && known_eq (coff, toff)))
    {
      if (to != from
	  && currval != VN_TOP
	  && !curr_undefined
	  /* We do not want to allow lattice transitions from one value
	     to another since that may lead to not terminating iteration
	     (see PR95049).  Since there's no convenient way to check
	     for the allowed transition of VAL -> PHI (loop entry value,
	     same on two PHIs, to same PHI result) we restrict the check
	     to invariants.  */
	  && curr_invariant
	  && is_gimple_min_invariant (to))
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file, " forced VARYING");
	  to = from;
	}
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, " (changed)\n");
      from_info->valnum = to;
      return true;
    }
  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "\n");
  return false;
}

/* Set all definitions in STMT to value number to themselves.
   Return true if a value number changed. */

static bool
defs_to_varying (gimple *stmt)
{
  bool changed = false;
  ssa_op_iter iter;
  def_operand_p defp;

  FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_ALL_DEFS)
    {
      tree def = DEF_FROM_PTR (defp);
      changed |= set_ssa_val_to (def, def);
    }
  return changed;
}

/* Visit a copy between LHS and RHS, return true if the value number
   changed.  */

static bool
visit_copy (tree lhs, tree rhs)
{
  /* Valueize.  */
  rhs = SSA_VAL (rhs);

  return set_ssa_val_to (lhs, rhs);
}

/* Lookup a value for OP in type WIDE_TYPE where the value in type of OP
   is the same.  */

static tree
valueized_wider_op (tree wide_type, tree op)
{
  if (TREE_CODE (op) == SSA_NAME)
    op = vn_valueize (op);

  /* Either we have the op widened available.  */
  tree ops[3] = {};
  ops[0] = op;
  tree tem = vn_nary_op_lookup_pieces (1, NOP_EXPR,
				       wide_type, ops, NULL);
  if (tem)
    return tem;

  /* Or the op is truncated from some existing value.  */
  if (TREE_CODE (op) == SSA_NAME)
    {
      gimple *def = SSA_NAME_DEF_STMT (op);
      if (is_gimple_assign (def)
	  && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
	{
	  tem = gimple_assign_rhs1 (def);
	  if (useless_type_conversion_p (wide_type, TREE_TYPE (tem)))
	    {
	      if (TREE_CODE (tem) == SSA_NAME)
		tem = vn_valueize (tem);
	      return tem;
	    }
	}
    }

  /* For constants simply extend it.  */
  if (TREE_CODE (op) == INTEGER_CST)
    return wide_int_to_tree (wide_type, wi::to_wide (op));

  return NULL_TREE;
}

/* Visit a nary operator RHS, value number it, and return true if the
   value number of LHS has changed as a result.  */

static bool
visit_nary_op (tree lhs, gassign *stmt)
{
  vn_nary_op_t vnresult;
  tree result = vn_nary_op_lookup_stmt (stmt, &vnresult);
  if (! result && vnresult)
    result = vn_nary_op_get_predicated_value (vnresult, gimple_bb (stmt));
  if (result)
    return set_ssa_val_to (lhs, result);

  /* Do some special pattern matching for redundancies of operations
     in different types.  */
  enum tree_code code = gimple_assign_rhs_code (stmt);
  tree type = TREE_TYPE (lhs);
  tree rhs1 = gimple_assign_rhs1 (stmt);
  switch (code)
    {
    CASE_CONVERT:
      /* Match arithmetic done in a different type where we can easily
         substitute the result from some earlier sign-changed or widened
	 operation.  */
      if (INTEGRAL_TYPE_P (type)
	  && TREE_CODE (rhs1) == SSA_NAME
	  /* We only handle sign-changes, zero-extension -> & mask or
	     sign-extension if we know the inner operation doesn't
	     overflow.  */
	  && (((TYPE_UNSIGNED (TREE_TYPE (rhs1))
		|| (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
		    && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (rhs1))))
	       && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (rhs1)))
	      || TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (rhs1))))
	{
	  gassign *def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (rhs1));
	  if (def
	      && (gimple_assign_rhs_code (def) == PLUS_EXPR
		  || gimple_assign_rhs_code (def) == MINUS_EXPR
		  || gimple_assign_rhs_code (def) == MULT_EXPR))
	    {
	      tree ops[3] = {};
	      /* Either we have the op widened available.  */
	      ops[0] = valueized_wider_op (type,
					   gimple_assign_rhs1 (def));
	      if (ops[0])
		ops[1] = valueized_wider_op (type,
					     gimple_assign_rhs2 (def));
	      if (ops[0] && ops[1])
		{
		  ops[0] = vn_nary_op_lookup_pieces
		      (2, gimple_assign_rhs_code (def), type, ops, NULL);
		  /* We have wider operation available.  */
		  if (ops[0]
		      /* If the leader is a wrapping operation we can
		         insert it for code hoisting w/o introducing
			 undefined overflow.  If it is not it has to
			 be available.  See PR86554.  */
		      && (TYPE_OVERFLOW_WRAPS (TREE_TYPE (ops[0]))
			  || (rpo_avail && vn_context_bb
			      && rpo_avail->eliminate_avail (vn_context_bb,
							     ops[0]))))
		    {
		      unsigned lhs_prec = TYPE_PRECISION (type);
		      unsigned rhs_prec = TYPE_PRECISION (TREE_TYPE (rhs1));
		      if (lhs_prec == rhs_prec
			  || (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
			      && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (rhs1))))
			{
			  gimple_match_op match_op (gimple_match_cond::UNCOND,
						    NOP_EXPR, type, ops[0]);
			  result = vn_nary_build_or_lookup (&match_op);
			  if (result)
			    {
			      bool changed = set_ssa_val_to (lhs, result);
			      vn_nary_op_insert_stmt (stmt, result);
			      return changed;
			    }
			}
		      else
			{
			  tree mask = wide_int_to_tree
			    (type, wi::mask (rhs_prec, false, lhs_prec));
			  gimple_match_op match_op (gimple_match_cond::UNCOND,
						    BIT_AND_EXPR,
						    TREE_TYPE (lhs),
						    ops[0], mask);
			  result = vn_nary_build_or_lookup (&match_op);
			  if (result)
			    {
			      bool changed = set_ssa_val_to (lhs, result);
			      vn_nary_op_insert_stmt (stmt, result);
			      return changed;
			    }
			}
		    }
		}
	    }
	}
      break;
    case BIT_AND_EXPR:
      if (INTEGRAL_TYPE_P (type)
	  && TREE_CODE (rhs1) == SSA_NAME
	  && TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST
	  && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1)
	  && default_vn_walk_kind != VN_NOWALK
	  && CHAR_BIT == 8
	  && BITS_PER_UNIT == 8
	  && BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN
	  && !integer_all_onesp (gimple_assign_rhs2 (stmt))
	  && !integer_zerop (gimple_assign_rhs2 (stmt)))
	{
	  gassign *ass = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (rhs1));
	  if (ass
	      && !gimple_has_volatile_ops (ass)
	      && vn_get_stmt_kind (ass) == VN_REFERENCE)
	    {
	      tree last_vuse = gimple_vuse (ass);
	      tree op = gimple_assign_rhs1 (ass);
	      tree result = vn_reference_lookup (op, gimple_vuse (ass),
						 default_vn_walk_kind,
						 NULL, true, &last_vuse,
						 gimple_assign_rhs2 (stmt));
	      if (result
		  && useless_type_conversion_p (TREE_TYPE (result),
						TREE_TYPE (op)))
		return set_ssa_val_to (lhs, result);
	    }
	}
      break;
    default:
      break;
    }

  bool changed = set_ssa_val_to (lhs, lhs);
  vn_nary_op_insert_stmt (stmt, lhs);
  return changed;
}

/* Visit a call STMT storing into LHS.  Return true if the value number
   of the LHS has changed as a result.  */

static bool
visit_reference_op_call (tree lhs, gcall *stmt)
{
  bool changed = false;
  struct vn_reference_s vr1;
  vn_reference_t vnresult = NULL;
  tree vdef = gimple_vdef (stmt);

  /* Non-ssa lhs is handled in copy_reference_ops_from_call.  */
  if (lhs && TREE_CODE (lhs) != SSA_NAME)
    lhs = NULL_TREE;

  vn_reference_lookup_call (stmt, &vnresult, &vr1);
  if (vnresult)
    {
      if (vnresult->result_vdef && vdef)
	changed |= set_ssa_val_to (vdef, vnresult->result_vdef);
      else if (vdef)
	/* If the call was discovered to be pure or const reflect
	   that as far as possible.  */
	changed |= set_ssa_val_to (vdef, vuse_ssa_val (gimple_vuse (stmt)));

      if (!vnresult->result && lhs)
	vnresult->result = lhs;

      if (vnresult->result && lhs)
	changed |= set_ssa_val_to (lhs, vnresult->result);
    }
  else
    {
      vn_reference_t vr2;
      vn_reference_s **slot;
      tree vdef_val = vdef;
      if (vdef)
	{
	  /* If we value numbered an indirect functions function to
	     one not clobbering memory value number its VDEF to its
	     VUSE.  */
	  tree fn = gimple_call_fn (stmt);
	  if (fn && TREE_CODE (fn) == SSA_NAME)
	    {
	      fn = SSA_VAL (fn);
	      if (TREE_CODE (fn) == ADDR_EXPR
		  && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
		  && (flags_from_decl_or_type (TREE_OPERAND (fn, 0))
		      & (ECF_CONST | ECF_PURE)))
		vdef_val = vuse_ssa_val (gimple_vuse (stmt));
	    }
	  changed |= set_ssa_val_to (vdef, vdef_val);
	}
      if (lhs)
	changed |= set_ssa_val_to (lhs, lhs);
      vr2 = XOBNEW (&vn_tables_obstack, vn_reference_s);
      vr2->vuse = vr1.vuse;
      /* As we are not walking the virtual operand chain we know the
	 shared_lookup_references are still original so we can re-use
	 them here.  */
      vr2->operands = vr1.operands.copy ();
      vr2->type = vr1.type;
      vr2->set = vr1.set;
      vr2->base_set = vr1.base_set;
      vr2->hashcode = vr1.hashcode;
      vr2->result = lhs;
      vr2->result_vdef = vdef_val;
      vr2->value_id = 0;
      slot = valid_info->references->find_slot_with_hash (vr2, vr2->hashcode,
							  INSERT);
      gcc_assert (!*slot);
      *slot = vr2;
      vr2->next = last_inserted_ref;
      last_inserted_ref = vr2;
    }

  return changed;
}

/* Visit a load from a reference operator RHS, part of STMT, value number it,
   and return true if the value number of the LHS has changed as a result.  */

static bool
visit_reference_op_load (tree lhs, tree op, gimple *stmt)
{
  bool changed = false;
  tree last_vuse;
  tree result;

  last_vuse = gimple_vuse (stmt);
  result = vn_reference_lookup (op, gimple_vuse (stmt),
				default_vn_walk_kind, NULL, true, &last_vuse);

  /* We handle type-punning through unions by value-numbering based
     on offset and size of the access.  Be prepared to handle a
     type-mismatch here via creating a VIEW_CONVERT_EXPR.  */
  if (result
      && !useless_type_conversion_p (TREE_TYPE (result), TREE_TYPE (op)))
    {
      /* Avoid the type punning in case the result mode has padding where
	 the op we lookup has not.  */
      if (maybe_lt (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (result))),
		    GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (op)))))
	result = NULL_TREE;
      else
	{
	  /* We will be setting the value number of lhs to the value number
	     of VIEW_CONVERT_EXPR <TREE_TYPE (result)> (result).
	     So first simplify and lookup this expression to see if it
	     is already available.  */
	  gimple_match_op res_op (gimple_match_cond::UNCOND,
				  VIEW_CONVERT_EXPR, TREE_TYPE (op), result);
	  result = vn_nary_build_or_lookup (&res_op);
	}

      /* When building the conversion fails avoid inserting the reference
         again.  */
      if (!result)
	return set_ssa_val_to (lhs, lhs);
    }

  if (result)
    changed = set_ssa_val_to (lhs, result);
  else
    {
      changed = set_ssa_val_to (lhs, lhs);
      vn_reference_insert (op, lhs, last_vuse, NULL_TREE);
    }

  return changed;
}


/* Visit a store to a reference operator LHS, part of STMT, value number it,
   and return true if the value number of the LHS has changed as a result.  */

static bool
visit_reference_op_store (tree lhs, tree op, gimple *stmt)
{
  bool changed = false;
  vn_reference_t vnresult = NULL;
  tree assign;
  bool resultsame = false;
  tree vuse = gimple_vuse (stmt);
  tree vdef = gimple_vdef (stmt);

  if (TREE_CODE (op) == SSA_NAME)
    op = SSA_VAL (op);

  /* First we want to lookup using the *vuses* from the store and see
     if there the last store to this location with the same address
     had the same value.

     The vuses represent the memory state before the store.  If the
     memory state, address, and value of the store is the same as the
     last store to this location, then this store will produce the
     same memory state as that store.

     In this case the vdef versions for this store are value numbered to those
     vuse versions, since they represent the same memory state after
     this store.

     Otherwise, the vdefs for the store are used when inserting into
     the table, since the store generates a new memory state.  */

  vn_reference_lookup (lhs, vuse, VN_NOWALK, &vnresult, false);
  if (vnresult
      && vnresult->result)
    {
      tree result = vnresult->result;
      gcc_checking_assert (TREE_CODE (result) != SSA_NAME
			   || result == SSA_VAL (result));
      resultsame = expressions_equal_p (result, op);
      if (resultsame)
	{
	  /* If the TBAA state isn't compatible for downstream reads
	     we cannot value-number the VDEFs the same.  */
	  ao_ref lhs_ref;
	  ao_ref_init (&lhs_ref, lhs);
	  alias_set_type set = ao_ref_alias_set (&lhs_ref);
	  alias_set_type base_set = ao_ref_base_alias_set (&lhs_ref);
	  if ((vnresult->set != set
	       && ! alias_set_subset_of (set, vnresult->set))
	      || (vnresult->base_set != base_set
		  && ! alias_set_subset_of (base_set, vnresult->base_set)))
	    resultsame = false;
	}
    }

  if (!resultsame)
    {
      /* Only perform the following when being called from PRE
	 which embeds tail merging.  */
      if (default_vn_walk_kind == VN_WALK)
	{
	  assign = build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, op);
	  vn_reference_lookup (assign, vuse, VN_NOWALK, &vnresult, false);
	  if (vnresult)
	    {
	      VN_INFO (vdef)->visited = true;
	      return set_ssa_val_to (vdef, vnresult->result_vdef);
	    }
	}

      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "No store match\n");
	  fprintf (dump_file, "Value numbering store ");
	  print_generic_expr (dump_file, lhs);
	  fprintf (dump_file, " to ");
	  print_generic_expr (dump_file, op);
	  fprintf (dump_file, "\n");
	}
      /* Have to set value numbers before insert, since insert is
	 going to valueize the references in-place.  */
      if (vdef)
	changed |= set_ssa_val_to (vdef, vdef);

      /* Do not insert structure copies into the tables.  */
      if (is_gimple_min_invariant (op)
	  || is_gimple_reg (op))
        vn_reference_insert (lhs, op, vdef, NULL);

      /* Only perform the following when being called from PRE
	 which embeds tail merging.  */
      if (default_vn_walk_kind == VN_WALK)
	{
	  assign = build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, op);
	  vn_reference_insert (assign, lhs, vuse, vdef);
	}
    }
  else
    {
      /* We had a match, so value number the vdef to have the value
	 number of the vuse it came from.  */

      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "Store matched earlier value, "
		 "value numbering store vdefs to matching vuses.\n");

      changed |= set_ssa_val_to (vdef, SSA_VAL (vuse));
    }

  return changed;
}

/* Visit and value number PHI, return true if the value number
   changed.  When BACKEDGES_VARYING_P is true then assume all
   backedge values are varying.  When INSERTED is not NULL then
   this is just a ahead query for a possible iteration, set INSERTED
   to true if we'd insert into the hashtable.  */

static bool
visit_phi (gimple *phi, bool *inserted, bool backedges_varying_p)
{
  tree result, sameval = VN_TOP, seen_undef = NULL_TREE;
  tree backedge_val = NULL_TREE;
  bool seen_non_backedge = false;
  tree sameval_base = NULL_TREE;
  poly_int64 soff, doff;
  unsigned n_executable = 0;
  edge_iterator ei;
  edge e;

  /* TODO: We could check for this in initialization, and replace this
     with a gcc_assert.  */
  if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (phi)))
    return set_ssa_val_to (PHI_RESULT (phi), PHI_RESULT (phi));

  /* We track whether a PHI was CSEd to to avoid excessive iterations
     that would be necessary only because the PHI changed arguments
     but not value.  */
  if (!inserted)
    gimple_set_plf (phi, GF_PLF_1, false);

  /* See if all non-TOP arguments have the same value.  TOP is
     equivalent to everything, so we can ignore it.  */
  FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds)
    if (e->flags & EDGE_EXECUTABLE)
      {
	tree def = PHI_ARG_DEF_FROM_EDGE (phi, e);

	++n_executable;
	if (TREE_CODE (def) == SSA_NAME)
	  {
	    if (!backedges_varying_p || !(e->flags & EDGE_DFS_BACK))
	      def = SSA_VAL (def);
	    if (e->flags & EDGE_DFS_BACK)
	      backedge_val = def;
	  }
	if (!(e->flags & EDGE_DFS_BACK))
	  seen_non_backedge = true;
	if (def == VN_TOP)
	  ;
	/* Ignore undefined defs for sameval but record one.  */
	else if (TREE_CODE (def) == SSA_NAME
		 && ! virtual_operand_p (def)
		 && ssa_undefined_value_p (def, false))
	  seen_undef = def;
	else if (sameval == VN_TOP)
	  sameval = def;
	else if (!expressions_equal_p (def, sameval))
	  {
	    /* We know we're arriving only with invariant addresses here,
	       try harder comparing them.  We can do some caching here
	       which we cannot do in expressions_equal_p.  */
	    if (TREE_CODE (def) == ADDR_EXPR
		&& TREE_CODE (sameval) == ADDR_EXPR
		&& sameval_base != (void *)-1)
	      {
		if (!sameval_base)
		  sameval_base = get_addr_base_and_unit_offset
				   (TREE_OPERAND (sameval, 0), &soff);
		if (!sameval_base)
		  sameval_base = (tree)(void *)-1;
		else if ((get_addr_base_and_unit_offset
			    (TREE_OPERAND (def, 0), &doff) == sameval_base)
			 && known_eq (soff, doff))
		  continue;
	      }
	    sameval = NULL_TREE;
	    break;
	  }
      }

  /* If the value we want to use is flowing over the backedge and we
     should take it as VARYING but it has a non-VARYING value drop to
     VARYING.
     If we value-number a virtual operand never value-number to the
     value from the backedge as that confuses the alias-walking code.
     See gcc.dg/torture/pr87176.c.  If the value is the same on a
     non-backedge everything is OK though.  */
  bool visited_p;
  if ((backedge_val
       && !seen_non_backedge
       && TREE_CODE (backedge_val) == SSA_NAME
       && sameval == backedge_val
       && (SSA_NAME_IS_VIRTUAL_OPERAND (backedge_val)
	   || SSA_VAL (backedge_val) != backedge_val))
      /* Do not value-number a virtual operand to sth not visited though
	 given that allows us to escape a region in alias walking.  */
      || (sameval
	  && TREE_CODE (sameval) == SSA_NAME
	  && !SSA_NAME_IS_DEFAULT_DEF (sameval)
	  && SSA_NAME_IS_VIRTUAL_OPERAND (sameval)
	  && (SSA_VAL (sameval, &visited_p), !visited_p)))
    /* Note this just drops to VARYING without inserting the PHI into
       the hashes.  */
    result = PHI_RESULT (phi);
  /* If none of the edges was executable keep the value-number at VN_TOP,
     if only a single edge is exectuable use its value.  */
  else if (n_executable <= 1)
    result = seen_undef ? seen_undef : sameval;
  /* If we saw only undefined values and VN_TOP use one of the
     undefined values.  */
  else if (sameval == VN_TOP)
    result = seen_undef ? seen_undef : sameval;
  /* First see if it is equivalent to a phi node in this block.  We prefer
     this as it allows IV elimination - see PRs 66502 and 67167.  */
  else if ((result = vn_phi_lookup (phi, backedges_varying_p)))
    {
      if (!inserted
	  && TREE_CODE (result) == SSA_NAME
	  && gimple_code (SSA_NAME_DEF_STMT (result)) == GIMPLE_PHI)
	{
	  gimple_set_plf (SSA_NAME_DEF_STMT (result), GF_PLF_1, true);
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "Marking CSEd to PHI node ");
	      print_gimple_expr (dump_file, SSA_NAME_DEF_STMT (result),
				 0, TDF_SLIM);
	      fprintf (dump_file, "\n");
	    }
	}
    }
  /* If all values are the same use that, unless we've seen undefined
     values as well and the value isn't constant.
     CCP/copyprop have the same restriction to not remove uninit warnings.  */
  else if (sameval
	   && (! seen_undef || is_gimple_min_invariant (sameval)))
    result = sameval;
  else
    {
      result = PHI_RESULT (phi);
      /* Only insert PHIs that are varying, for constant value numbers
         we mess up equivalences otherwise as we are only comparing
	 the immediate controlling predicates.  */
      vn_phi_insert (phi, result, backedges_varying_p);
      if (inserted)
	*inserted = true;
    }

  return set_ssa_val_to (PHI_RESULT (phi), result);
}

/* Try to simplify RHS using equivalences and constant folding.  */

static tree
try_to_simplify (gassign *stmt)
{
  enum tree_code code = gimple_assign_rhs_code (stmt);
  tree tem;

  /* For stores we can end up simplifying a SSA_NAME rhs.  Just return
     in this case, there is no point in doing extra work.  */
  if (code == SSA_NAME)
    return NULL_TREE;

  /* First try constant folding based on our current lattice.  */
  mprts_hook = vn_lookup_simplify_result;
  tem = gimple_fold_stmt_to_constant_1 (stmt, vn_valueize, vn_valueize);
  mprts_hook = NULL;
  if (tem
      && (TREE_CODE (tem) == SSA_NAME
	  || is_gimple_min_invariant (tem)))
    return tem;

  return NULL_TREE;
}

/* Visit and value number STMT, return true if the value number
   changed.  */

static bool
visit_stmt (gimple *stmt, bool backedges_varying_p = false)
{
  bool changed = false;

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Value numbering stmt = ");
      print_gimple_stmt (dump_file, stmt, 0);
    }

  if (gimple_code (stmt) == GIMPLE_PHI)
    changed = visit_phi (stmt, NULL, backedges_varying_p);
  else if (gimple_has_volatile_ops (stmt))
    changed = defs_to_varying (stmt);
  else if (gassign *ass = dyn_cast <gassign *> (stmt))
    {
      enum tree_code code = gimple_assign_rhs_code (ass);
      tree lhs = gimple_assign_lhs (ass);
      tree rhs1 = gimple_assign_rhs1 (ass);
      tree simplified;

      /* Shortcut for copies. Simplifying copies is pointless,
	 since we copy the expression and value they represent.  */
      if (code == SSA_NAME
	  && TREE_CODE (lhs) == SSA_NAME)
	{
	  changed = visit_copy (lhs, rhs1);
	  goto done;
	}
      simplified = try_to_simplify (ass);
      if (simplified)
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "RHS ");
	      print_gimple_expr (dump_file, ass, 0);
	      fprintf (dump_file, " simplified to ");
	      print_generic_expr (dump_file, simplified);
	      fprintf (dump_file, "\n");
	    }
	}
      /* Setting value numbers to constants will occasionally
	 screw up phi congruence because constants are not
	 uniquely associated with a single ssa name that can be
	 looked up.  */
      if (simplified
	  && is_gimple_min_invariant (simplified)
	  && TREE_CODE (lhs) == SSA_NAME)
	{
	  changed = set_ssa_val_to (lhs, simplified);
	  goto done;
	}
      else if (simplified
	       && TREE_CODE (simplified) == SSA_NAME
	       && TREE_CODE (lhs) == SSA_NAME)
	{
	  changed = visit_copy (lhs, simplified);
	  goto done;
	}

      if ((TREE_CODE (lhs) == SSA_NAME
	   /* We can substitute SSA_NAMEs that are live over
	      abnormal edges with their constant value.  */
	   && !(gimple_assign_copy_p (ass)
		&& is_gimple_min_invariant (rhs1))
	   && !(simplified
		&& is_gimple_min_invariant (simplified))
	   && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
	  /* Stores or copies from SSA_NAMEs that are live over
	     abnormal edges are a problem.  */
	  || (code == SSA_NAME
	      && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1)))
	changed = defs_to_varying (ass);
      else if (REFERENCE_CLASS_P (lhs)
	       || DECL_P (lhs))
	changed = visit_reference_op_store (lhs, rhs1, ass);
      else if (TREE_CODE (lhs) == SSA_NAME)
	{
	  if ((gimple_assign_copy_p (ass)
	       && is_gimple_min_invariant (rhs1))
	      || (simplified
		  && is_gimple_min_invariant (simplified)))
	    {
	      if (simplified)
		changed = set_ssa_val_to (lhs, simplified);
	      else
		changed = set_ssa_val_to (lhs, rhs1);
	    }
	  else
	    {
	      /* Visit the original statement.  */
	      switch (vn_get_stmt_kind (ass))
		{
		case VN_NARY:
		  changed = visit_nary_op (lhs, ass);
		  break;
		case VN_REFERENCE:
		  changed = visit_reference_op_load (lhs, rhs1, ass);
		  break;
		default:
		  changed = defs_to_varying (ass);
		  break;
		}
	    }
	}
      else
	changed = defs_to_varying (ass);
    }
  else if (gcall *call_stmt = dyn_cast <gcall *> (stmt))
    {
      tree lhs = gimple_call_lhs (call_stmt);
      if (lhs && TREE_CODE (lhs) == SSA_NAME)
	{
	  /* Try constant folding based on our current lattice.  */
	  tree simplified = gimple_fold_stmt_to_constant_1 (call_stmt,
							    vn_valueize);
	  if (simplified)
	    {
	      if (dump_file && (dump_flags & TDF_DETAILS))
		{
		  fprintf (dump_file, "call ");
		  print_gimple_expr (dump_file, call_stmt, 0);
		  fprintf (dump_file, " simplified to ");
		  print_generic_expr (dump_file, simplified);
		  fprintf (dump_file, "\n");
		}
	    }
	  /* Setting value numbers to constants will occasionally
	     screw up phi congruence because constants are not
	     uniquely associated with a single ssa name that can be
	     looked up.  */
	  if (simplified
	      && is_gimple_min_invariant (simplified))
	    {
	      changed = set_ssa_val_to (lhs, simplified);
	      if (gimple_vdef (call_stmt))
		changed |= set_ssa_val_to (gimple_vdef (call_stmt),
					   SSA_VAL (gimple_vuse (call_stmt)));
	      goto done;
	    }
	  else if (simplified
		   && TREE_CODE (simplified) == SSA_NAME)
	    {
	      changed = visit_copy (lhs, simplified);
	      if (gimple_vdef (call_stmt))
		changed |= set_ssa_val_to (gimple_vdef (call_stmt),
					   SSA_VAL (gimple_vuse (call_stmt)));
	      goto done;
	    }
	  else if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
	    {
	      changed = defs_to_varying (call_stmt);
	      goto done;
	    }
	}

      /* Pick up flags from a devirtualization target.  */
      tree fn = gimple_call_fn (stmt);
      int extra_fnflags = 0;
      if (fn && TREE_CODE (fn) == SSA_NAME)
	{
	  fn = SSA_VAL (fn);
	  if (TREE_CODE (fn) == ADDR_EXPR
	      && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL)
	    extra_fnflags = flags_from_decl_or_type (TREE_OPERAND (fn, 0));
	}
      if (!gimple_call_internal_p (call_stmt)
	  && (/* Calls to the same function with the same vuse
		 and the same operands do not necessarily return the same
		 value, unless they're pure or const.  */
	      ((gimple_call_flags (call_stmt) | extra_fnflags)
	       & (ECF_PURE | ECF_CONST))
	      /* If calls have a vdef, subsequent calls won't have
		 the same incoming vuse.  So, if 2 calls with vdef have the
		 same vuse, we know they're not subsequent.
		 We can value number 2 calls to the same function with the
		 same vuse and the same operands which are not subsequent
		 the same, because there is no code in the program that can
		 compare the 2 values...  */
	      || (gimple_vdef (call_stmt)
		  /* ... unless the call returns a pointer which does
		     not alias with anything else.  In which case the
		     information that the values are distinct are encoded
		     in the IL.  */
		  && !(gimple_call_return_flags (call_stmt) & ERF_NOALIAS)
		  /* Only perform the following when being called from PRE
		     which embeds tail merging.  */
		  && default_vn_walk_kind == VN_WALK)))
	changed = visit_reference_op_call (lhs, call_stmt);
      else
	changed = defs_to_varying (call_stmt);
    }
  else
    changed = defs_to_varying (stmt);
 done:
  return changed;
}


/* Allocate a value number table.  */

static void
allocate_vn_table (vn_tables_t table, unsigned size)
{
  table->phis = new vn_phi_table_type (size);
  table->nary = new vn_nary_op_table_type (size);
  table->references = new vn_reference_table_type (size);
}

/* Free a value number table.  */

static void
free_vn_table (vn_tables_t table)
{
  /* Walk over elements and release vectors.  */
  vn_reference_iterator_type hir;
  vn_reference_t vr;
  FOR_EACH_HASH_TABLE_ELEMENT (*table->references, vr, vn_reference_t, hir)
    vr->operands.release ();
  delete table->phis;
  table->phis = NULL;
  delete table->nary;
  table->nary = NULL;
  delete table->references;
  table->references = NULL;
}

/* Set *ID according to RESULT.  */

static void
set_value_id_for_result (tree result, unsigned int *id)
{
  if (result && TREE_CODE (result) == SSA_NAME)
    *id = VN_INFO (result)->value_id;
  else if (result && is_gimple_min_invariant (result))
    *id = get_or_alloc_constant_value_id (result);
  else
    *id = get_next_value_id ();
}

/* Set the value ids in the valid hash tables.  */

static void
set_hashtable_value_ids (void)
{
  vn_nary_op_iterator_type hin;
  vn_phi_iterator_type hip;
  vn_reference_iterator_type hir;
  vn_nary_op_t vno;
  vn_reference_t vr;
  vn_phi_t vp;

  /* Now set the value ids of the things we had put in the hash
     table.  */

  FOR_EACH_HASH_TABLE_ELEMENT (*valid_info->nary, vno, vn_nary_op_t, hin)
    if (! vno->predicated_values)
      set_value_id_for_result (vno->u.result, &vno->value_id);

  FOR_EACH_HASH_TABLE_ELEMENT (*valid_info->phis, vp, vn_phi_t, hip)
    set_value_id_for_result (vp->result, &vp->value_id);

  FOR_EACH_HASH_TABLE_ELEMENT (*valid_info->references, vr, vn_reference_t,
			       hir)
    set_value_id_for_result (vr->result, &vr->value_id);
}

/* Return the maximum value id we have ever seen.  */

unsigned int
get_max_value_id (void)
{
  return next_value_id;
}

/* Return the next unique value id.  */

unsigned int
get_next_value_id (void)
{
  return next_value_id++;
}


/* Compare two expressions E1 and E2 and return true if they are equal.  */

bool
expressions_equal_p (tree e1, tree e2)
{
  /* The obvious case.  */
  if (e1 == e2)
    return true;

  /* If either one is VN_TOP consider them equal.  */
  if (e1 == VN_TOP || e2 == VN_TOP)
    return true;

  /* If only one of them is null, they cannot be equal.  */
  if (!e1 || !e2)
    return false;

  /* Now perform the actual comparison.  */
  if (TREE_CODE (e1) == TREE_CODE (e2)
      && operand_equal_p (e1, e2, OEP_PURE_SAME))
    return true;

  return false;
}


/* Return true if the nary operation NARY may trap.  This is a copy
   of stmt_could_throw_1_p adjusted to the SCCVN IL.  */

bool
vn_nary_may_trap (vn_nary_op_t nary)
{
  tree type;
  tree rhs2 = NULL_TREE;
  bool honor_nans = false;
  bool honor_snans = false;
  bool fp_operation = false;
  bool honor_trapv = false;
  bool handled, ret;
  unsigned i;

  if (TREE_CODE_CLASS (nary->opcode) == tcc_comparison
      || TREE_CODE_CLASS (nary->opcode) == tcc_unary
      || TREE_CODE_CLASS (nary->opcode) == tcc_binary)
    {
      type = nary->type;
      fp_operation = FLOAT_TYPE_P (type);
      if (fp_operation)
	{
	  honor_nans = flag_trapping_math && !flag_finite_math_only;
	  honor_snans = flag_signaling_nans != 0;
	}
      else if (INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_TRAPS (type))
	honor_trapv = true;
    }
  if (nary->length >= 2)
    rhs2 = nary->op[1];
  ret = operation_could_trap_helper_p (nary->opcode, fp_operation,
				       honor_trapv, honor_nans, honor_snans,
				       rhs2, &handled);
  if (handled && ret)
    return true;

  for (i = 0; i < nary->length; ++i)
    if (tree_could_trap_p (nary->op[i]))
      return true;

  return false;
}

/* Return true if the reference operation REF may trap.  */

bool
vn_reference_may_trap (vn_reference_t ref)
{
  switch (ref->operands[0].opcode)
    {
    case MODIFY_EXPR:
    case CALL_EXPR:
      /* We do not handle calls.  */
    case ADDR_EXPR:
      /* And toplevel address computations never trap.  */
      return false;
    default:;
    }

  vn_reference_op_t op;
  unsigned i;
  FOR_EACH_VEC_ELT (ref->operands, i, op)
    {
      switch (op->opcode)
	{
	case WITH_SIZE_EXPR:
	case TARGET_MEM_REF:
	  /* Always variable.  */
	  return true;
	case COMPONENT_REF:
	  if (op->op1 && TREE_CODE (op->op1) == SSA_NAME)
	    return true;
	  break;
	case ARRAY_RANGE_REF:
	case ARRAY_REF:
	  if (TREE_CODE (op->op0) == SSA_NAME)
	    return true;
	  break;
	case MEM_REF:
	  /* Nothing interesting in itself, the base is separate.  */
	  break;
	/* The following are the address bases.  */
	case SSA_NAME:
	  return true;
	case ADDR_EXPR:
	  if (op->op0)
	    return tree_could_trap_p (TREE_OPERAND (op->op0, 0));
	  return false;
	default:;
	}
    }
  return false;
}

eliminate_dom_walker::eliminate_dom_walker (cdi_direction direction,
					    bitmap inserted_exprs_)
  : dom_walker (direction), do_pre (inserted_exprs_ != NULL),
    el_todo (0), eliminations (0), insertions (0),
    inserted_exprs (inserted_exprs_)
{
  need_eh_cleanup = BITMAP_ALLOC (NULL);
  need_ab_cleanup = BITMAP_ALLOC (NULL);
}

eliminate_dom_walker::~eliminate_dom_walker ()
{
  BITMAP_FREE (need_eh_cleanup);
  BITMAP_FREE (need_ab_cleanup);
}

/* Return a leader for OP that is available at the current point of the
   eliminate domwalk.  */

tree
eliminate_dom_walker::eliminate_avail (basic_block, tree op)
{
  tree valnum = VN_INFO (op)->valnum;
  if (TREE_CODE (valnum) == SSA_NAME)
    {
      if (SSA_NAME_IS_DEFAULT_DEF (valnum))
	return valnum;
      if (avail.length () > SSA_NAME_VERSION (valnum))
	return avail[SSA_NAME_VERSION (valnum)];
    }
  else if (is_gimple_min_invariant (valnum))
    return valnum;
  return NULL_TREE;
}

/* At the current point of the eliminate domwalk make OP available.  */

void
eliminate_dom_walker::eliminate_push_avail (basic_block, tree op)
{
  tree valnum = VN_INFO (op)->valnum;
  if (TREE_CODE (valnum) == SSA_NAME)
    {
      if (avail.length () <= SSA_NAME_VERSION (valnum))
	avail.safe_grow_cleared (SSA_NAME_VERSION (valnum) + 1);
      tree pushop = op;
      if (avail[SSA_NAME_VERSION (valnum)])
	pushop = avail[SSA_NAME_VERSION (valnum)];
      avail_stack.safe_push (pushop);
      avail[SSA_NAME_VERSION (valnum)] = op;
    }
}

/* Insert the expression recorded by SCCVN for VAL at *GSI.  Returns
   the leader for the expression if insertion was successful.  */

tree
eliminate_dom_walker::eliminate_insert (basic_block bb,
					gimple_stmt_iterator *gsi, tree val)
{
  /* We can insert a sequence with a single assignment only.  */
  gimple_seq stmts = VN_INFO (val)->expr;
  if (!gimple_seq_singleton_p (stmts))
    return NULL_TREE;
  gassign *stmt = dyn_cast <gassign *> (gimple_seq_first_stmt (stmts));
  if (!stmt
      || (!CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
	  && gimple_assign_rhs_code (stmt) != VIEW_CONVERT_EXPR
	  && gimple_assign_rhs_code (stmt) != BIT_FIELD_REF
	  && (gimple_assign_rhs_code (stmt) != BIT_AND_EXPR
	      || TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST)))
    return NULL_TREE;

  tree op = gimple_assign_rhs1 (stmt);
  if (gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR
      || gimple_assign_rhs_code (stmt) == BIT_FIELD_REF)
    op = TREE_OPERAND (op, 0);
  tree leader = TREE_CODE (op) == SSA_NAME ? eliminate_avail (bb, op) : op;
  if (!leader)
    return NULL_TREE;

  tree res;
  stmts = NULL;
  if (gimple_assign_rhs_code (stmt) == BIT_FIELD_REF)
    res = gimple_build (&stmts, BIT_FIELD_REF,
			TREE_TYPE (val), leader,
			TREE_OPERAND (gimple_assign_rhs1 (stmt), 1),
			TREE_OPERAND (gimple_assign_rhs1 (stmt), 2));
  else if (gimple_assign_rhs_code (stmt) == BIT_AND_EXPR)
    res = gimple_build (&stmts, BIT_AND_EXPR,
			TREE_TYPE (val), leader, gimple_assign_rhs2 (stmt));
  else
    res = gimple_build (&stmts, gimple_assign_rhs_code (stmt),
			TREE_TYPE (val), leader);
  if (TREE_CODE (res) != SSA_NAME
      || SSA_NAME_IS_DEFAULT_DEF (res)
      || gimple_bb (SSA_NAME_DEF_STMT (res)))
    {
      gimple_seq_discard (stmts);

      /* During propagation we have to treat SSA info conservatively
         and thus we can end up simplifying the inserted expression
	 at elimination time to sth not defined in stmts.  */
      /* But then this is a redundancy we failed to detect.  Which means
         res now has two values.  That doesn't play well with how
	 we track availability here, so give up.  */
      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  if (TREE_CODE (res) == SSA_NAME)
	    res = eliminate_avail (bb, res);
	  if (res)
	    {
	      fprintf (dump_file, "Failed to insert expression for value ");
	      print_generic_expr (dump_file, val);
	      fprintf (dump_file, " which is really fully redundant to ");
	      print_generic_expr (dump_file, res);
	      fprintf (dump_file, "\n");
	    }
	}

      return NULL_TREE;
    }
  else
    {
      gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
      VN_INFO (res)->valnum = val;
      VN_INFO (res)->visited = true;
    }

  insertions++;
  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Inserted ");
      print_gimple_stmt (dump_file, SSA_NAME_DEF_STMT (res), 0);
    }

  return res;
}

void
eliminate_dom_walker::eliminate_stmt (basic_block b, gimple_stmt_iterator *gsi)
{
  tree sprime = NULL_TREE;
  gimple *stmt = gsi_stmt (*gsi);
  tree lhs = gimple_get_lhs (stmt);
  if (lhs && TREE_CODE (lhs) == SSA_NAME
      && !gimple_has_volatile_ops (stmt)
      /* See PR43491.  Do not replace a global register variable when
	 it is a the RHS of an assignment.  Do replace local register
	 variables since gcc does not guarantee a local variable will
	 be allocated in register.
	 ???  The fix isn't effective here.  This should instead
	 be ensured by not value-numbering them the same but treating
	 them like volatiles?  */
      && !(gimple_assign_single_p (stmt)
	   && (TREE_CODE (gimple_assign_rhs1 (stmt)) == VAR_DECL
	       && DECL_HARD_REGISTER (gimple_assign_rhs1 (stmt))
	       && is_global_var (gimple_assign_rhs1 (stmt)))))
    {
      sprime = eliminate_avail (b, lhs);
      if (!sprime)
	{
	  /* If there is no existing usable leader but SCCVN thinks
	     it has an expression it wants to use as replacement,
	     insert that.  */
	  tree val = VN_INFO (lhs)->valnum;
	  if (val != VN_TOP
	      && TREE_CODE (val) == SSA_NAME
	      && VN_INFO (val)->needs_insertion
	      && VN_INFO (val)->expr != NULL
	      && (sprime = eliminate_insert (b, gsi, val)) != NULL_TREE)
	    eliminate_push_avail (b, sprime);
	}

      /* If this now constitutes a copy duplicate points-to
	 and range info appropriately.  This is especially
	 important for inserted code.  See tree-ssa-copy.c
	 for similar code.  */
      if (sprime
	  && TREE_CODE (sprime) == SSA_NAME)
	{
	  basic_block sprime_b = gimple_bb (SSA_NAME_DEF_STMT (sprime));
	  if (POINTER_TYPE_P (TREE_TYPE (lhs))
	      && SSA_NAME_PTR_INFO (lhs)
	      && ! SSA_NAME_PTR_INFO (sprime))
	    {
	      duplicate_ssa_name_ptr_info (sprime,
					   SSA_NAME_PTR_INFO (lhs));
	      if (b != sprime_b)
		mark_ptr_info_alignment_unknown
		    (SSA_NAME_PTR_INFO (sprime));
	    }
	  else if (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
		   && SSA_NAME_RANGE_INFO (lhs)
		   && ! SSA_NAME_RANGE_INFO (sprime)
		   && b == sprime_b)
	    duplicate_ssa_name_range_info (sprime,
					   SSA_NAME_RANGE_TYPE (lhs),
					   SSA_NAME_RANGE_INFO (lhs));
	}

      /* Inhibit the use of an inserted PHI on a loop header when
	 the address of the memory reference is a simple induction
	 variable.  In other cases the vectorizer won't do anything
	 anyway (either it's loop invariant or a complicated
	 expression).  */
      if (sprime
	  && TREE_CODE (sprime) == SSA_NAME
	  && do_pre
	  && (flag_tree_loop_vectorize || flag_tree_parallelize_loops > 1)
	  && loop_outer (b->loop_father)
	  && has_zero_uses (sprime)
	  && bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (sprime))
	  && gimple_assign_load_p (stmt))
	{
	  gimple *def_stmt = SSA_NAME_DEF_STMT (sprime);
	  basic_block def_bb = gimple_bb (def_stmt);
	  if (gimple_code (def_stmt) == GIMPLE_PHI
	      && def_bb->loop_father->header == def_bb)
	    {
	      loop_p loop = def_bb->loop_father;
	      ssa_op_iter iter;
	      tree op;
	      bool found = false;
	      FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
		{
		  affine_iv iv;
		  def_bb = gimple_bb (SSA_NAME_DEF_STMT (op));
		  if (def_bb
		      && flow_bb_inside_loop_p (loop, def_bb)
		      && simple_iv (loop, loop, op, &iv, true))
		    {
		      found = true;
		      break;
		    }
		}
	      if (found)
		{
		  if (dump_file && (dump_flags & TDF_DETAILS))
		    {
		      fprintf (dump_file, "Not replacing ");
		      print_gimple_expr (dump_file, stmt, 0);
		      fprintf (dump_file, " with ");
		      print_generic_expr (dump_file, sprime);
		      fprintf (dump_file, " which would add a loop"
			       " carried dependence to loop %d\n",
			       loop->num);
		    }
		  /* Don't keep sprime available.  */
		  sprime = NULL_TREE;
		}
	    }
	}

      if (sprime)
	{
	  /* If we can propagate the value computed for LHS into
	     all uses don't bother doing anything with this stmt.  */
	  if (may_propagate_copy (lhs, sprime))
	    {
	      /* Mark it for removal.  */
	      to_remove.safe_push (stmt);

	      /* ???  Don't count copy/constant propagations.  */
	      if (gimple_assign_single_p (stmt)
		  && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
		      || gimple_assign_rhs1 (stmt) == sprime))
		return;

	      if (dump_file && (dump_flags & TDF_DETAILS))
		{
		  fprintf (dump_file, "Replaced ");
		  print_gimple_expr (dump_file, stmt, 0);
		  fprintf (dump_file, " with ");
		  print_generic_expr (dump_file, sprime);
		  fprintf (dump_file, " in all uses of ");
		  print_gimple_stmt (dump_file, stmt, 0);
		}

	      eliminations++;
	      return;
	    }

	  /* If this is an assignment from our leader (which
	     happens in the case the value-number is a constant)
	     then there is nothing to do.  Likewise if we run into
	     inserted code that needed a conversion because of
	     our type-agnostic value-numbering of loads.  */
	  if ((gimple_assign_single_p (stmt)
	       || (is_gimple_assign (stmt)
		   && (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
		       || gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR)))
	      && sprime == gimple_assign_rhs1 (stmt))
	    return;

	  /* Else replace its RHS.  */
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "Replaced ");
	      print_gimple_expr (dump_file, stmt, 0);
	      fprintf (dump_file, " with ");
	      print_generic_expr (dump_file, sprime);
	      fprintf (dump_file, " in ");
	      print_gimple_stmt (dump_file, stmt, 0);
	    }
	  eliminations++;

	  bool can_make_abnormal_goto = (is_gimple_call (stmt)
					 && stmt_can_make_abnormal_goto (stmt));
	  gimple *orig_stmt = stmt;
	  if (!useless_type_conversion_p (TREE_TYPE (lhs),
					  TREE_TYPE (sprime)))
	    {
	      /* We preserve conversions to but not from function or method
		 types.  This asymmetry makes it necessary to re-instantiate
		 conversions here.  */
	      if (POINTER_TYPE_P (TREE_TYPE (lhs))
		  && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (lhs))))
		sprime = fold_convert (TREE_TYPE (lhs), sprime);
	      else
		gcc_unreachable ();
	    }
	  tree vdef = gimple_vdef (stmt);
	  tree vuse = gimple_vuse (stmt);
	  propagate_tree_value_into_stmt (gsi, sprime);
	  stmt = gsi_stmt (*gsi);
	  update_stmt (stmt);
	  /* In case the VDEF on the original stmt was released, value-number
	     it to the VUSE.  This is to make vuse_ssa_val able to skip
	     released virtual operands.  */
	  if (vdef != gimple_vdef (stmt))
	    {
	      gcc_assert (SSA_NAME_IN_FREE_LIST (vdef));
	      VN_INFO (vdef)->valnum = vuse;
	    }

	  /* If we removed EH side-effects from the statement, clean
	     its EH information.  */
	  if (maybe_clean_or_replace_eh_stmt (orig_stmt, stmt))
	    {
	      bitmap_set_bit (need_eh_cleanup,
			      gimple_bb (stmt)->index);
	      if (dump_file && (dump_flags & TDF_DETAILS))
		fprintf (dump_file, "  Removed EH side-effects.\n");
	    }

	  /* Likewise for AB side-effects.  */
	  if (can_make_abnormal_goto
	      && !stmt_can_make_abnormal_goto (stmt))
	    {
	      bitmap_set_bit (need_ab_cleanup,
			      gimple_bb (stmt)->index);
	      if (dump_file && (dump_flags & TDF_DETAILS))
		fprintf (dump_file, "  Removed AB side-effects.\n");
	    }

	  return;
	}
    }

  /* If the statement is a scalar store, see if the expression
     has the same value number as its rhs.  If so, the store is
     dead.  */
  if (gimple_assign_single_p (stmt)
      && !gimple_has_volatile_ops (stmt)
      && !is_gimple_reg (gimple_assign_lhs (stmt))
      && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
	  || is_gimple_min_invariant (gimple_assign_rhs1 (stmt))))
    {
      tree rhs = gimple_assign_rhs1 (stmt);
      vn_reference_t vnresult;
      /* ???  gcc.dg/torture/pr91445.c shows that we lookup a boolean
         typed load of a byte known to be 0x11 as 1 so a store of
	 a boolean 1 is detected as redundant.  Because of this we
	 have to make sure to lookup with a ref where its size
	 matches the precision.  */
      tree lookup_lhs = lhs;
      if (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
	  && (TREE_CODE (lhs) != COMPONENT_REF
	      || !DECL_BIT_FIELD_TYPE (TREE_OPERAND (lhs, 1)))
	  && !type_has_mode_precision_p (TREE_TYPE (lhs)))
	{
	  if (TREE_CODE (lhs) == COMPONENT_REF
	      || TREE_CODE (lhs) == MEM_REF)
	    {
	      tree ltype = build_nonstandard_integer_type
				(TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (lhs))),
				 TYPE_UNSIGNED (TREE_TYPE (lhs)));
	      if (TREE_CODE (lhs) == COMPONENT_REF)
		{
		  tree foff = component_ref_field_offset (lhs);
		  tree f = TREE_OPERAND (lhs, 1);
		  if (!poly_int_tree_p (foff))
		    lookup_lhs = NULL_TREE;
		  else
		    lookup_lhs = build3 (BIT_FIELD_REF, ltype,
					 TREE_OPERAND (lhs, 0),
					 TYPE_SIZE (TREE_TYPE (lhs)),
					 bit_from_pos
					   (foff, DECL_FIELD_BIT_OFFSET (f)));
		}
	      else
		lookup_lhs = build2 (MEM_REF, ltype,
				     TREE_OPERAND (lhs, 0),
				     TREE_OPERAND (lhs, 1));
	    }
	  else
	    lookup_lhs = NULL_TREE;
	}
      tree val = NULL_TREE;
      if (lookup_lhs)
	val = vn_reference_lookup (lookup_lhs, gimple_vuse (stmt),
				   VN_WALKREWRITE, &vnresult, false);
      if (TREE_CODE (rhs) == SSA_NAME)
	rhs = VN_INFO (rhs)->valnum;
      if (val
	  && (operand_equal_p (val, rhs, 0)
	      /* Due to the bitfield lookups above we can get bit
		 interpretations of the same RHS as values here.  Those
		 are redundant as well.  */
	      || (TREE_CODE (val) == SSA_NAME
		  && gimple_assign_single_p (SSA_NAME_DEF_STMT (val))
		  && (val = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (val)))
		  && TREE_CODE (val) == VIEW_CONVERT_EXPR
		  && TREE_OPERAND (val, 0) == rhs)))
	{
	  /* We can only remove the later store if the former aliases
	     at least all accesses the later one does or if the store
	     was to readonly memory storing the same value.  */
	  ao_ref lhs_ref;
	  ao_ref_init (&lhs_ref, lhs);
	  alias_set_type set = ao_ref_alias_set (&lhs_ref);
	  alias_set_type base_set = ao_ref_base_alias_set (&lhs_ref);
	  if (! vnresult
	      || ((vnresult->set == set
		   || alias_set_subset_of (set, vnresult->set))
		  && (vnresult->base_set == base_set
		      || alias_set_subset_of (base_set, vnresult->base_set))))
	    {
	      if (dump_file && (dump_flags & TDF_DETAILS))
		{
		  fprintf (dump_file, "Deleted redundant store ");
		  print_gimple_stmt (dump_file, stmt, 0);
		}

	      /* Queue stmt for removal.  */
	      to_remove.safe_push (stmt);
	      return;
	    }
	}
    }

  /* If this is a control statement value numbering left edges
     unexecuted on force the condition in a way consistent with
     that.  */
  if (gcond *cond = dyn_cast <gcond *> (stmt))
    {
      if ((EDGE_SUCC (b, 0)->flags & EDGE_EXECUTABLE)
	  ^ (EDGE_SUCC (b, 1)->flags & EDGE_EXECUTABLE))
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "Removing unexecutable edge from ");
	      print_gimple_stmt (dump_file, stmt, 0);
	    }
	  if (((EDGE_SUCC (b, 0)->flags & EDGE_TRUE_VALUE) != 0)
	      == ((EDGE_SUCC (b, 0)->flags & EDGE_EXECUTABLE) != 0))
	    gimple_cond_make_true (cond);
	  else
	    gimple_cond_make_false (cond);
	  update_stmt (cond);
	  el_todo |= TODO_cleanup_cfg;
	  return;
	}
    }

  bool can_make_abnormal_goto = stmt_can_make_abnormal_goto (stmt);
  bool was_noreturn = (is_gimple_call (stmt)
		       && gimple_call_noreturn_p (stmt));
  tree vdef = gimple_vdef (stmt);
  tree vuse = gimple_vuse (stmt);

  /* If we didn't replace the whole stmt (or propagate the result
     into all uses), replace all uses on this stmt with their
     leaders.  */
  bool modified = false;
  use_operand_p use_p;
  ssa_op_iter iter;
  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
    {
      tree use = USE_FROM_PTR (use_p);
      /* ???  The call code above leaves stmt operands un-updated.  */
      if (TREE_CODE (use) != SSA_NAME)
	continue;
      tree sprime;
      if (SSA_NAME_IS_DEFAULT_DEF (use))
	/* ???  For default defs BB shouldn't matter, but we have to
	   solve the inconsistency between rpo eliminate and
	   dom eliminate avail valueization first.  */
	sprime = eliminate_avail (b, use);
      else
	/* Look for sth available at the definition block of the argument.
	   This avoids inconsistencies between availability there which
	   decides if the stmt can be removed and availability at the
	   use site.  The SSA property ensures that things available
	   at the definition are also available at uses.  */
	sprime = eliminate_avail (gimple_bb (SSA_NAME_DEF_STMT (use)), use);
      if (sprime && sprime != use
	  && may_propagate_copy (use, sprime)
	  /* We substitute into debug stmts to avoid excessive
	     debug temporaries created by removed stmts, but we need
	     to avoid doing so for inserted sprimes as we never want
	     to create debug temporaries for them.  */
	  && (!inserted_exprs
	      || TREE_CODE (sprime) != SSA_NAME
	      || !is_gimple_debug (stmt)
	      || !bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (sprime))))
	{
	  propagate_value (use_p, sprime);
	  modified = true;
	}
    }

  /* Fold the stmt if modified, this canonicalizes MEM_REFs we propagated
     into which is a requirement for the IPA devirt machinery.  */
  gimple *old_stmt = stmt;
  if (modified)
    {
      /* If a formerly non-invariant ADDR_EXPR is turned into an
	 invariant one it was on a separate stmt.  */
      if (gimple_assign_single_p (stmt)
	  && TREE_CODE (gimple_assign_rhs1 (stmt)) == ADDR_EXPR)
	recompute_tree_invariant_for_addr_expr (gimple_assign_rhs1 (stmt));
      gimple_stmt_iterator prev = *gsi;
      gsi_prev (&prev);
      if (fold_stmt (gsi))
	{
	  /* fold_stmt may have created new stmts inbetween
	     the previous stmt and the folded stmt.  Mark
	     all defs created there as varying to not confuse
	     the SCCVN machinery as we're using that even during
	     elimination.  */
	  if (gsi_end_p (prev))
	    prev = gsi_start_bb (b);
	  else
	    gsi_next (&prev);
	  if (gsi_stmt (prev) != gsi_stmt (*gsi))
	    do
	      {
		tree def;
		ssa_op_iter dit;
		FOR_EACH_SSA_TREE_OPERAND (def, gsi_stmt (prev),
					   dit, SSA_OP_ALL_DEFS)
		    /* As existing DEFs may move between stmts
		       only process new ones.  */
		    if (! has_VN_INFO (def))
		      {
			VN_INFO (def)->valnum = def;
			VN_INFO (def)->visited = true;
		      }
		if (gsi_stmt (prev) == gsi_stmt (*gsi))
		  break;
		gsi_next (&prev);
	      }
	    while (1);
	}
      stmt = gsi_stmt (*gsi);
      /* In case we folded the stmt away schedule the NOP for removal.  */
      if (gimple_nop_p (stmt))
	to_remove.safe_push (stmt);
    }

  /* Visit indirect calls and turn them into direct calls if
     possible using the devirtualization machinery.  Do this before
     checking for required EH/abnormal/noreturn cleanup as devird
     may expose more of those.  */
  if (gcall *call_stmt = dyn_cast <gcall *> (stmt))
    {
      tree fn = gimple_call_fn (call_stmt);
      if (fn
	  && flag_devirtualize
	  && virtual_method_call_p (fn))
	{
	  tree otr_type = obj_type_ref_class (fn);
	  unsigned HOST_WIDE_INT otr_tok
	      = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (fn));
	  tree instance;
	  ipa_polymorphic_call_context context (current_function_decl,
						fn, stmt, &instance);
	  context.get_dynamic_type (instance, OBJ_TYPE_REF_OBJECT (fn),
				    otr_type, stmt, NULL);
	  bool final;
	  vec <cgraph_node *> targets
	      = possible_polymorphic_call_targets (obj_type_ref_class (fn),
						   otr_tok, context, &final);
	  if (dump_file)
	    dump_possible_polymorphic_call_targets (dump_file,
						    obj_type_ref_class (fn),
						    otr_tok, context);
	  if (final && targets.length () <= 1 && dbg_cnt (devirt))
	    {
	      tree fn;
	      if (targets.length () == 1)
		fn = targets[0]->decl;
	      else
		fn = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
	      if (dump_enabled_p ())
		{
		  dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt,
				   "converting indirect call to "
				   "function %s\n",
				   lang_hooks.decl_printable_name (fn, 2));
		}
	      gimple_call_set_fndecl (call_stmt, fn);
	      /* If changing the call to __builtin_unreachable
		 or similar noreturn function, adjust gimple_call_fntype
		 too.  */
	      if (gimple_call_noreturn_p (call_stmt)
		  && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fn)))
		  && TYPE_ARG_TYPES (TREE_TYPE (fn))
		  && (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fn)))
		      == void_type_node))
		gimple_call_set_fntype (call_stmt, TREE_TYPE (fn));
	      maybe_remove_unused_call_args (cfun, call_stmt);
	      modified = true;
	    }
	}
    }

  if (modified)
    {
      /* When changing a call into a noreturn call, cfg cleanup
	 is needed to fix up the noreturn call.  */
      if (!was_noreturn
	  && is_gimple_call (stmt) && gimple_call_noreturn_p (stmt))
	to_fixup.safe_push  (stmt);
      /* When changing a condition or switch into one we know what
	 edge will be executed, schedule a cfg cleanup.  */
      if ((gimple_code (stmt) == GIMPLE_COND
	   && (gimple_cond_true_p (as_a <gcond *> (stmt))
	       || gimple_cond_false_p (as_a <gcond *> (stmt))))
	  || (gimple_code (stmt) == GIMPLE_SWITCH
	      && TREE_CODE (gimple_switch_index
			    (as_a <gswitch *> (stmt))) == INTEGER_CST))
	el_todo |= TODO_cleanup_cfg;
      /* If we removed EH side-effects from the statement, clean
	 its EH information.  */
      if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
	{
	  bitmap_set_bit (need_eh_cleanup,
			  gimple_bb (stmt)->index);
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file, "  Removed EH side-effects.\n");
	}
      /* Likewise for AB side-effects.  */
      if (can_make_abnormal_goto
	  && !stmt_can_make_abnormal_goto (stmt))
	{
	  bitmap_set_bit (need_ab_cleanup,
			  gimple_bb (stmt)->index);
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file, "  Removed AB side-effects.\n");
	}
      update_stmt (stmt);
      /* In case the VDEF on the original stmt was released, value-number
         it to the VUSE.  This is to make vuse_ssa_val able to skip
	 released virtual operands.  */
      if (vdef && SSA_NAME_IN_FREE_LIST (vdef))
	VN_INFO (vdef)->valnum = vuse;
    }

  /* Make new values available - for fully redundant LHS we
     continue with the next stmt above and skip this.  */
  def_operand_p defp;
  FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_DEF)
    eliminate_push_avail (b, DEF_FROM_PTR (defp));
}

/* Perform elimination for the basic-block B during the domwalk.  */

edge
eliminate_dom_walker::before_dom_children (basic_block b)
{
  /* Mark new bb.  */
  avail_stack.safe_push (NULL_TREE);

  /* Skip unreachable blocks marked unreachable during the SCCVN domwalk.  */
  if (!(b->flags & BB_EXECUTABLE))
    return NULL;

  vn_context_bb = b;

  for (gphi_iterator gsi = gsi_start_phis (b); !gsi_end_p (gsi);)
    {
      gphi *phi = gsi.phi ();
      tree res = PHI_RESULT (phi);

      if (virtual_operand_p (res))
	{
	  gsi_next (&gsi);
	  continue;
	}

      tree sprime = eliminate_avail (b, res);
      if (sprime
	  && sprime != res)
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "Replaced redundant PHI node defining ");
	      print_generic_expr (dump_file, res);
	      fprintf (dump_file, " with ");
	      print_generic_expr (dump_file, sprime);
	      fprintf (dump_file, "\n");
	    }

	  /* If we inserted this PHI node ourself, it's not an elimination.  */
	  if (! inserted_exprs
	      || ! bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (res)))
	    eliminations++;

	  /* If we will propagate into all uses don't bother to do
	     anything.  */
	  if (may_propagate_copy (res, sprime))
	    {
	      /* Mark the PHI for removal.  */
	      to_remove.safe_push (phi);
	      gsi_next (&gsi);
	      continue;
	    }

	  remove_phi_node (&gsi, false);

	  if (!useless_type_conversion_p (TREE_TYPE (res), TREE_TYPE (sprime)))
	    sprime = fold_convert (TREE_TYPE (res), sprime);
	  gimple *stmt = gimple_build_assign (res, sprime);
	  gimple_stmt_iterator gsi2 = gsi_after_labels (b);
	  gsi_insert_before (&gsi2, stmt, GSI_NEW_STMT);
	  continue;
	}

      eliminate_push_avail (b, res);
      gsi_next (&gsi);
    }

  for (gimple_stmt_iterator gsi = gsi_start_bb (b);
       !gsi_end_p (gsi);
       gsi_next (&gsi))
    eliminate_stmt (b, &gsi);

  /* Replace destination PHI arguments.  */
  edge_iterator ei;
  edge e;
  FOR_EACH_EDGE (e, ei, b->succs)
    if (e->flags & EDGE_EXECUTABLE)
      for (gphi_iterator gsi = gsi_start_phis (e->dest);
	   !gsi_end_p (gsi);
	   gsi_next (&gsi))
	{
	  gphi *phi = gsi.phi ();
	  use_operand_p use_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e);
	  tree arg = USE_FROM_PTR (use_p);
	  if (TREE_CODE (arg) != SSA_NAME
	      || virtual_operand_p (arg))
	    continue;
	  tree sprime = eliminate_avail (b, arg);
	  if (sprime && may_propagate_copy (arg, sprime))
	    propagate_value (use_p, sprime);
	}

  vn_context_bb = NULL;

  return NULL;
}

/* Make no longer available leaders no longer available.  */

void
eliminate_dom_walker::after_dom_children (basic_block)
{
  tree entry;
  while ((entry = avail_stack.pop ()) != NULL_TREE)
    {
      tree valnum = VN_INFO (entry)->valnum;
      tree old = avail[SSA_NAME_VERSION (valnum)];
      if (old == entry)
	avail[SSA_NAME_VERSION (valnum)] = NULL_TREE;
      else
	avail[SSA_NAME_VERSION (valnum)] = entry;
    }
}

/* Remove queued stmts and perform delayed cleanups.  */

unsigned
eliminate_dom_walker::eliminate_cleanup (bool region_p)
{
  statistics_counter_event (cfun, "Eliminated", eliminations);
  statistics_counter_event (cfun, "Insertions", insertions);

  /* We cannot remove stmts during BB walk, especially not release SSA
     names there as this confuses the VN machinery.  The stmts ending
     up in to_remove are either stores or simple copies.
     Remove stmts in reverse order to make debug stmt creation possible.  */
  while (!to_remove.is_empty ())
    {
      bool do_release_defs = true;
      gimple *stmt = to_remove.pop ();

      /* When we are value-numbering a region we do not require exit PHIs to
	 be present so we have to make sure to deal with uses outside of the
	 region of stmts that we thought are eliminated.
	 ??? Note we may be confused by uses in dead regions we didn't run
	 elimination on.  Rather than checking individual uses we accept
	 dead copies to be generated here (gcc.c-torture/execute/20060905-1.c
	 contains such example).  */
      if (region_p)
	{
	  if (gphi *phi = dyn_cast <gphi *> (stmt))
	    {
	      tree lhs = gimple_phi_result (phi);
	      if (!has_zero_uses (lhs))
		{
		  if (dump_file && (dump_flags & TDF_DETAILS))
		    fprintf (dump_file, "Keeping eliminated stmt live "
			     "as copy because of out-of-region uses\n");
		  tree sprime = eliminate_avail (gimple_bb (stmt), lhs);
		  gimple *copy = gimple_build_assign (lhs, sprime);
		  gimple_stmt_iterator gsi
		    = gsi_after_labels (gimple_bb (stmt));
		  gsi_insert_before (&gsi, copy, GSI_SAME_STMT);
		  do_release_defs = false;
		}
	    }
	  else if (tree lhs = gimple_get_lhs (stmt))
	    if (TREE_CODE (lhs) == SSA_NAME
		&& !has_zero_uses (lhs))
	      {
		if (dump_file && (dump_flags & TDF_DETAILS))
		  fprintf (dump_file, "Keeping eliminated stmt live "
			   "as copy because of out-of-region uses\n");
		tree sprime = eliminate_avail (gimple_bb (stmt), lhs);
		gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
		if (is_gimple_assign (stmt))
		  {
		    gimple_assign_set_rhs_from_tree (&gsi, sprime);
		    stmt = gsi_stmt (gsi);
		    update_stmt (stmt);
		    if (maybe_clean_or_replace_eh_stmt (stmt, stmt))
		      bitmap_set_bit (need_eh_cleanup, gimple_bb (stmt)->index);
		    continue;
		  }
		else
		  {
		    gimple *copy = gimple_build_assign (lhs, sprime);
		    gsi_insert_before (&gsi, copy, GSI_SAME_STMT);
		    do_release_defs = false;
		  }
	      }
	}

      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "Removing dead stmt ");
	  print_gimple_stmt (dump_file, stmt, 0, TDF_NONE);
	}

      gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
      if (gimple_code (stmt) == GIMPLE_PHI)
	remove_phi_node (&gsi, do_release_defs);
      else
	{
	  basic_block bb = gimple_bb (stmt);
	  unlink_stmt_vdef (stmt);
	  if (gsi_remove (&gsi, true))
	    bitmap_set_bit (need_eh_cleanup, bb->index);
	  if (is_gimple_call (stmt) && stmt_can_make_abnormal_goto (stmt))
	    bitmap_set_bit (need_ab_cleanup, bb->index);
	  if (do_release_defs)
	    release_defs (stmt);
	}

      /* Removing a stmt may expose a forwarder block.  */
      el_todo |= TODO_cleanup_cfg;
    }

  /* Fixup stmts that became noreturn calls.  This may require splitting
     blocks and thus isn't possible during the dominator walk.  Do this
     in reverse order so we don't inadvertedly remove a stmt we want to
     fixup by visiting a dominating now noreturn call first.  */
  while (!to_fixup.is_empty ())
    {
      gimple *stmt = to_fixup.pop ();

      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "Fixing up noreturn call ");
	  print_gimple_stmt (dump_file, stmt, 0);
	}

      if (fixup_noreturn_call (stmt))
	el_todo |= TODO_cleanup_cfg;
    }

  bool do_eh_cleanup = !bitmap_empty_p (need_eh_cleanup);
  bool do_ab_cleanup = !bitmap_empty_p (need_ab_cleanup);

  if (do_eh_cleanup)
    gimple_purge_all_dead_eh_edges (need_eh_cleanup);

  if (do_ab_cleanup)
    gimple_purge_all_dead_abnormal_call_edges (need_ab_cleanup);

  if (do_eh_cleanup || do_ab_cleanup)
    el_todo |= TODO_cleanup_cfg;

  return el_todo;
}

/* Eliminate fully redundant computations.  */

unsigned
eliminate_with_rpo_vn (bitmap inserted_exprs)
{
  eliminate_dom_walker walker (CDI_DOMINATORS, inserted_exprs);

  eliminate_dom_walker *saved_rpo_avail = rpo_avail;
  rpo_avail = &walker;
  walker.walk (cfun->cfg->x_entry_block_ptr);
  rpo_avail = saved_rpo_avail;

  return walker.eliminate_cleanup ();
}

static unsigned
do_rpo_vn (function *fn, edge entry, bitmap exit_bbs,
	   bool iterate, bool eliminate);

void
run_rpo_vn (vn_lookup_kind kind)
{
  default_vn_walk_kind = kind;
  do_rpo_vn (cfun, NULL, NULL, true, false);

  /* ???  Prune requirement of these.  */
  constant_to_value_id = new hash_table<vn_constant_hasher> (23);
  constant_value_ids = BITMAP_ALLOC (NULL);

  /* Initialize the value ids and prune out remaining VN_TOPs
     from dead code.  */
  tree name;
  unsigned i;
  FOR_EACH_SSA_NAME (i, name, cfun)
    {
      vn_ssa_aux_t info = VN_INFO (name);
      if (!info->visited
	  || info->valnum == VN_TOP)
	info->valnum = name;
      if (info->valnum == name)
	info->value_id = get_next_value_id ();
      else if (is_gimple_min_invariant (info->valnum))
	info->value_id = get_or_alloc_constant_value_id (info->valnum);
    }

  /* Propagate.  */
  FOR_EACH_SSA_NAME (i, name, cfun)
    {
      vn_ssa_aux_t info = VN_INFO (name);
      if (TREE_CODE (info->valnum) == SSA_NAME
	  && info->valnum != name
	  && info->value_id != VN_INFO (info->valnum)->value_id)
	info->value_id = VN_INFO (info->valnum)->value_id;
    }

  set_hashtable_value_ids ();

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Value numbers:\n");
      FOR_EACH_SSA_NAME (i, name, cfun)
	{
	  if (VN_INFO (name)->visited
	      && SSA_VAL (name) != name)
	    {
	      print_generic_expr (dump_file, name);
	      fprintf (dump_file, " = ");
	      print_generic_expr (dump_file, SSA_VAL (name));
	      fprintf (dump_file, " (%04d)\n", VN_INFO (name)->value_id);
	    }
	}
    }
}

/* Free VN associated data structures.  */

void
free_rpo_vn (void)
{
  free_vn_table (valid_info);
  XDELETE (valid_info);
  obstack_free (&vn_tables_obstack, NULL);
  obstack_free (&vn_tables_insert_obstack, NULL);

  vn_ssa_aux_iterator_type it;
  vn_ssa_aux_t info;
  FOR_EACH_HASH_TABLE_ELEMENT (*vn_ssa_aux_hash, info, vn_ssa_aux_t, it)
    if (info->needs_insertion)
      release_ssa_name (info->name);
  obstack_free (&vn_ssa_aux_obstack, NULL);
  delete vn_ssa_aux_hash;

  delete constant_to_value_id;
  constant_to_value_id = NULL;
  BITMAP_FREE (constant_value_ids);
}

/* Hook for maybe_push_res_to_seq, lookup the expression in the VN tables.  */

static tree
vn_lookup_simplify_result (gimple_match_op *res_op)
{
  if (!res_op->code.is_tree_code ())
    return NULL_TREE;
  tree *ops = res_op->ops;
  unsigned int length = res_op->num_ops;
  if (res_op->code == CONSTRUCTOR
      /* ???  We're arriving here with SCCVNs view, decomposed CONSTRUCTOR
         and GIMPLEs / match-and-simplifies, CONSTRUCTOR as GENERIC tree.  */
      && TREE_CODE (res_op->ops[0]) == CONSTRUCTOR)
    {
      length = CONSTRUCTOR_NELTS (res_op->ops[0]);
      ops = XALLOCAVEC (tree, length);
      for (unsigned i = 0; i < length; ++i)
	ops[i] = CONSTRUCTOR_ELT (res_op->ops[0], i)->value;
    }
  vn_nary_op_t vnresult = NULL;
  tree res = vn_nary_op_lookup_pieces (length, (tree_code) res_op->code,
				       res_op->type, ops, &vnresult);
  /* If this is used from expression simplification make sure to
     return an available expression.  */
  if (res && TREE_CODE (res) == SSA_NAME && mprts_hook && rpo_avail)
    res = rpo_avail->eliminate_avail (vn_context_bb, res);
  return res;
}

/* Return a leader for OPs value that is valid at BB.  */

tree
rpo_elim::eliminate_avail (basic_block bb, tree op)
{
  bool visited;
  tree valnum = SSA_VAL (op, &visited);
  /* If we didn't visit OP then it must be defined outside of the
     region we process and also dominate it.  So it is available.  */
  if (!visited)
    return op;
  if (TREE_CODE (valnum) == SSA_NAME)
    {
      if (SSA_NAME_IS_DEFAULT_DEF (valnum))
	return valnum;
      vn_avail *av = VN_INFO (valnum)->avail;
      if (!av)
	return NULL_TREE;
      if (av->location == bb->index)
	/* On tramp3d 90% of the cases are here.  */
	return ssa_name (av->leader);
      do
	{
	  basic_block abb = BASIC_BLOCK_FOR_FN (cfun, av->location);
	  /* ???  During elimination we have to use availability at the
	     definition site of a use we try to replace.  This
	     is required to not run into inconsistencies because
	     of dominated_by_p_w_unex behavior and removing a definition
	     while not replacing all uses.
	     ???  We could try to consistently walk dominators
	     ignoring non-executable regions.  The nearest common
	     dominator of bb and abb is where we can stop walking.  We
	     may also be able to "pre-compute" (bits of) the next immediate
	     (non-)dominator during the RPO walk when marking edges as
	     executable.  */
	  if (dominated_by_p_w_unex (bb, abb))
	    {
	      tree leader = ssa_name (av->leader);
	      /* Prevent eliminations that break loop-closed SSA.  */
	      if (loops_state_satisfies_p (LOOP_CLOSED_SSA)
		  && ! SSA_NAME_IS_DEFAULT_DEF (leader)
		  && ! flow_bb_inside_loop_p (gimple_bb (SSA_NAME_DEF_STMT
							 (leader))->loop_father,
					      bb))
		return NULL_TREE;
	      if (dump_file && (dump_flags & TDF_DETAILS))
		{
		  print_generic_expr (dump_file, leader);
		  fprintf (dump_file, " is available for ");
		  print_generic_expr (dump_file, valnum);
		  fprintf (dump_file, "\n");
		}
	      /* On tramp3d 99% of the _remaining_ cases succeed at
	         the first enty.  */
	      return leader;
	    }
	  /* ???  Can we somehow skip to the immediate dominator
	     RPO index (bb_to_rpo)?  Again, maybe not worth, on
	     tramp3d the worst number of elements in the vector is 9.  */
	  av = av->next;
	}
      while (av);
    }
  else if (valnum != VN_TOP)
    /* valnum is is_gimple_min_invariant.  */
    return valnum;
  return NULL_TREE;
}

/* Make LEADER a leader for its value at BB.  */

void
rpo_elim::eliminate_push_avail (basic_block bb, tree leader)
{
  tree valnum = VN_INFO (leader)->valnum;
  if (valnum == VN_TOP
      || is_gimple_min_invariant (valnum))
    return;
  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Making available beyond BB%d ", bb->index);
      print_generic_expr (dump_file, leader);
      fprintf (dump_file, " for value ");
      print_generic_expr (dump_file, valnum);
      fprintf (dump_file, "\n");
    }
  vn_ssa_aux_t value = VN_INFO (valnum);
  vn_avail *av;
  if (m_avail_freelist)
    {
      av = m_avail_freelist;
      m_avail_freelist = m_avail_freelist->next;
    }
  else
    av = XOBNEW (&vn_ssa_aux_obstack, vn_avail);
  av->location = bb->index;
  av->leader = SSA_NAME_VERSION (leader);
  av->next = value->avail;
  value->avail = av;
}

/* Valueization hook for RPO VN plus required state.  */

tree
rpo_vn_valueize (tree name)
{
  if (TREE_CODE (name) == SSA_NAME)
    {
      vn_ssa_aux_t val = VN_INFO (name);
      if (val)
	{
	  tree tem = val->valnum;
	  if (tem != VN_TOP && tem != name)
	    {
	      if (TREE_CODE (tem) != SSA_NAME)
		return tem;
	      /* For all values we only valueize to an available leader
		 which means we can use SSA name info without restriction.  */
	      tem = rpo_avail->eliminate_avail (vn_context_bb, tem);
	      if (tem)
		return tem;
	    }
	}
    }
  return name;
}

/* Insert on PRED_E predicates derived from CODE OPS being true besides the
   inverted condition.  */

static void
insert_related_predicates_on_edge (enum tree_code code, tree *ops, edge pred_e)
{
  switch (code)
    {
    case LT_EXPR:
      /* a < b -> a {!,<}= b */
      vn_nary_op_insert_pieces_predicated (2, NE_EXPR, boolean_type_node,
					   ops, boolean_true_node, 0, pred_e);
      vn_nary_op_insert_pieces_predicated (2, LE_EXPR, boolean_type_node,
					   ops, boolean_true_node, 0, pred_e);
      /* a < b -> ! a {>,=} b */
      vn_nary_op_insert_pieces_predicated (2, GT_EXPR, boolean_type_node,
					   ops, boolean_false_node, 0, pred_e);
      vn_nary_op_insert_pieces_predicated (2, EQ_EXPR, boolean_type_node,
					   ops, boolean_false_node, 0, pred_e);
      break;
    case GT_EXPR:
      /* a > b -> a {!,>}= b */
      vn_nary_op_insert_pieces_predicated (2, NE_EXPR, boolean_type_node,
					   ops, boolean_true_node, 0, pred_e);
      vn_nary_op_insert_pieces_predicated (2, GE_EXPR, boolean_type_node,
					   ops, boolean_true_node, 0, pred_e);
      /* a > b -> ! a {<,=} b */
      vn_nary_op_insert_pieces_predicated (2, LT_EXPR, boolean_type_node,
					   ops, boolean_false_node, 0, pred_e);
      vn_nary_op_insert_pieces_predicated (2, EQ_EXPR, boolean_type_node,
					   ops, boolean_false_node, 0, pred_e);
      break;
    case EQ_EXPR:
      /* a == b -> ! a {<,>} b */
      vn_nary_op_insert_pieces_predicated (2, LT_EXPR, boolean_type_node,
					   ops, boolean_false_node, 0, pred_e);
      vn_nary_op_insert_pieces_predicated (2, GT_EXPR, boolean_type_node,
					   ops, boolean_false_node, 0, pred_e);
      break;
    case LE_EXPR:
    case GE_EXPR:
    case NE_EXPR:
      /* Nothing besides inverted condition.  */
      break;
    default:;
    }
}

/* Main stmt worker for RPO VN, process BB.  */

static unsigned
process_bb (rpo_elim &avail, basic_block bb,
	    bool bb_visited, bool iterate_phis, bool iterate, bool eliminate,
	    bool do_region, bitmap exit_bbs, bool skip_phis)
{
  unsigned todo = 0;
  edge_iterator ei;
  edge e;

  vn_context_bb = bb;

  /* If we are in loop-closed SSA preserve this state.  This is
     relevant when called on regions from outside of FRE/PRE.  */
  bool lc_phi_nodes = false;
  if (!skip_phis
      && loops_state_satisfies_p (LOOP_CLOSED_SSA))
    FOR_EACH_EDGE (e, ei, bb->preds)
      if (e->src->loop_father != e->dest->loop_father
	  && flow_loop_nested_p (e->dest->loop_father,
				 e->src->loop_father))
	{
	  lc_phi_nodes = true;
	  break;
	}

  /* When we visit a loop header substitute into loop info.  */
  if (!iterate && eliminate && bb->loop_father->header == bb)
    {
      /* Keep fields in sync with substitute_in_loop_info.  */
      if (bb->loop_father->nb_iterations)
	bb->loop_father->nb_iterations
	  = simplify_replace_tree (bb->loop_father->nb_iterations,
				   NULL_TREE, NULL_TREE, &vn_valueize_wrapper);
    }

  /* Value-number all defs in the basic-block.  */
  if (!skip_phis)
    for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
	 gsi_next (&gsi))
      {
	gphi *phi = gsi.phi ();
	tree res = PHI_RESULT (phi);
	vn_ssa_aux_t res_info = VN_INFO (res);
	if (!bb_visited)
	  {
	    gcc_assert (!res_info->visited);
	    res_info->valnum = VN_TOP;
	    res_info->visited = true;
	  }

	/* When not iterating force backedge values to varying.  */
	visit_stmt (phi, !iterate_phis);
	if (virtual_operand_p (res))
	  continue;

	/* Eliminate */
	/* The interesting case is gcc.dg/tree-ssa/pr22230.c for correctness
	   how we handle backedges and availability.
	   And gcc.dg/tree-ssa/ssa-sccvn-2.c for optimization.  */
	tree val = res_info->valnum;
	if (res != val && !iterate && eliminate)
	  {
	    if (tree leader = avail.eliminate_avail (bb, res))
	      {
		if (leader != res
		    /* Preserve loop-closed SSA form.  */
		    && (! lc_phi_nodes
			|| is_gimple_min_invariant (leader)))
		  {
		    if (dump_file && (dump_flags & TDF_DETAILS))
		      {
			fprintf (dump_file, "Replaced redundant PHI node "
				 "defining ");
			print_generic_expr (dump_file, res);
			fprintf (dump_file, " with ");
			print_generic_expr (dump_file, leader);
			fprintf (dump_file, "\n");
		      }
		    avail.eliminations++;

		    if (may_propagate_copy (res, leader))
		      {
			/* Schedule for removal.  */
			avail.to_remove.safe_push (phi);
			continue;
		      }
		    /* ???  Else generate a copy stmt.  */
		  }
	      }
	  }
	/* Only make defs available that not already are.  But make
	   sure loop-closed SSA PHI node defs are picked up for
	   downstream uses.  */
	if (lc_phi_nodes
	    || res == val
	    || ! avail.eliminate_avail (bb, res))
	  avail.eliminate_push_avail (bb, res);
      }

  /* For empty BBs mark outgoing edges executable.  For non-empty BBs
     we do this when processing the last stmt as we have to do this
     before elimination which otherwise forces GIMPLE_CONDs to
     if (1 != 0) style when seeing non-executable edges.  */
  if (gsi_end_p (gsi_start_bb (bb)))
    {
      FOR_EACH_EDGE (e, ei, bb->succs)
	{
	  if (!(e->flags & EDGE_EXECUTABLE))
	    {
	      if (dump_file && (dump_flags & TDF_DETAILS))
		fprintf (dump_file,
			 "marking outgoing edge %d -> %d executable\n",
			 e->src->index, e->dest->index);
	      e->flags |= EDGE_EXECUTABLE;
	      e->dest->flags |= BB_EXECUTABLE;
	    }
	  else if (!(e->dest->flags & BB_EXECUTABLE))
	    {
	      if (dump_file && (dump_flags & TDF_DETAILS))
		fprintf (dump_file,
			 "marking destination block %d reachable\n",
			 e->dest->index);
	      e->dest->flags |= BB_EXECUTABLE;
	    }
	}
    }
  for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
       !gsi_end_p (gsi); gsi_next (&gsi))
    {
      ssa_op_iter i;
      tree op;
      if (!bb_visited)
	{
	  FOR_EACH_SSA_TREE_OPERAND (op, gsi_stmt (gsi), i, SSA_OP_ALL_DEFS)
	    {
	      vn_ssa_aux_t op_info = VN_INFO (op);
	      gcc_assert (!op_info->visited);
	      op_info->valnum = VN_TOP;
	      op_info->visited = true;
	    }

	  /* We somehow have to deal with uses that are not defined
	     in the processed region.  Forcing unvisited uses to
	     varying here doesn't play well with def-use following during
	     expression simplification, so we deal with this by checking
	     the visited flag in SSA_VAL.  */
	}

      visit_stmt (gsi_stmt (gsi));

      gimple *last = gsi_stmt (gsi);
      e = NULL;
      switch (gimple_code (last))
	{
	case GIMPLE_SWITCH:
	  e = find_taken_edge (bb, vn_valueize (gimple_switch_index
						(as_a <gswitch *> (last))));
	  break;
	case GIMPLE_COND:
	  {
	    tree lhs = vn_valueize (gimple_cond_lhs (last));
	    tree rhs = vn_valueize (gimple_cond_rhs (last));
	    tree val = gimple_simplify (gimple_cond_code (last),
					boolean_type_node, lhs, rhs,
					NULL, vn_valueize);
	    /* If the condition didn't simplfy see if we have recorded
	       an expression from sofar taken edges.  */
	    if (! val || TREE_CODE (val) != INTEGER_CST)
	      {
		vn_nary_op_t vnresult;
		tree ops[2];
		ops[0] = lhs;
		ops[1] = rhs;
		val = vn_nary_op_lookup_pieces (2, gimple_cond_code (last),
						boolean_type_node, ops,
						&vnresult);
		/* Did we get a predicated value?  */
		if (! val && vnresult && vnresult->predicated_values)
		  {
		    val = vn_nary_op_get_predicated_value (vnresult, bb);
		    if (val && dump_file && (dump_flags & TDF_DETAILS))
		      {
			fprintf (dump_file, "Got predicated value ");
			print_generic_expr (dump_file, val, TDF_NONE);
			fprintf (dump_file, " for ");
			print_gimple_stmt (dump_file, last, TDF_SLIM);
		      }
		  }
	      }
	    if (val)
	      e = find_taken_edge (bb, val);
	    if (! e)
	      {
		/* If we didn't manage to compute the taken edge then
		   push predicated expressions for the condition itself
		   and related conditions to the hashtables.  This allows
		   simplification of redundant conditions which is
		   important as early cleanup.  */
		edge true_e, false_e;
		extract_true_false_edges_from_block (bb, &true_e, &false_e);
		enum tree_code code = gimple_cond_code (last);
		enum tree_code icode
		  = invert_tree_comparison (code, HONOR_NANS (lhs));
		tree ops[2];
		ops[0] = lhs;
		ops[1] = rhs;
		if (do_region
		    && bitmap_bit_p (exit_bbs, true_e->dest->index))
		  true_e = NULL;
		if (do_region
		    && bitmap_bit_p (exit_bbs, false_e->dest->index))
		  false_e = NULL;
		if (true_e)
		  vn_nary_op_insert_pieces_predicated
		    (2, code, boolean_type_node, ops,
		     boolean_true_node, 0, true_e);
		if (false_e)
		  vn_nary_op_insert_pieces_predicated
		    (2, code, boolean_type_node, ops,
		     boolean_false_node, 0, false_e);
		if (icode != ERROR_MARK)
		  {
		    if (true_e)
		      vn_nary_op_insert_pieces_predicated
			(2, icode, boolean_type_node, ops,
			 boolean_false_node, 0, true_e);
		    if (false_e)
		      vn_nary_op_insert_pieces_predicated
			(2, icode, boolean_type_node, ops,
			 boolean_true_node, 0, false_e);
		  }
		/* Relax for non-integers, inverted condition handled
		   above.  */
		if (INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
		  {
		    if (true_e)
		      insert_related_predicates_on_edge (code, ops, true_e);
		    if (false_e)
		      insert_related_predicates_on_edge (icode, ops, false_e);
		  }
	      }
	    break;
	  }
	case GIMPLE_GOTO:
	  e = find_taken_edge (bb, vn_valueize (gimple_goto_dest (last)));
	  break;
	default:
	  e = NULL;
	}
      if (e)
	{
	  todo = TODO_cleanup_cfg;
	  if (!(e->flags & EDGE_EXECUTABLE))
	    {
	      if (dump_file && (dump_flags & TDF_DETAILS))
		fprintf (dump_file,
			 "marking known outgoing %sedge %d -> %d executable\n",
			 e->flags & EDGE_DFS_BACK ? "back-" : "",
			 e->src->index, e->dest->index);
	      e->flags |= EDGE_EXECUTABLE;
	      e->dest->flags |= BB_EXECUTABLE;
	    }
	  else if (!(e->dest->flags & BB_EXECUTABLE))
	    {
	      if (dump_file && (dump_flags & TDF_DETAILS))
		fprintf (dump_file,
			 "marking destination block %d reachable\n",
			 e->dest->index);
	      e->dest->flags |= BB_EXECUTABLE;
	    }
	}
      else if (gsi_one_before_end_p (gsi))
	{
	  FOR_EACH_EDGE (e, ei, bb->succs)
	    {
	      if (!(e->flags & EDGE_EXECUTABLE))
		{
		  if (dump_file && (dump_flags & TDF_DETAILS))
		    fprintf (dump_file,
			     "marking outgoing edge %d -> %d executable\n",
			     e->src->index, e->dest->index);
		  e->flags |= EDGE_EXECUTABLE;
		  e->dest->flags |= BB_EXECUTABLE;
		}
	      else if (!(e->dest->flags & BB_EXECUTABLE))
		{
		  if (dump_file && (dump_flags & TDF_DETAILS))
		    fprintf (dump_file,
			     "marking destination block %d reachable\n",
			     e->dest->index);
		  e->dest->flags |= BB_EXECUTABLE;
		}
	    }
	}

      /* Eliminate.  That also pushes to avail.  */
      if (eliminate && ! iterate)
	avail.eliminate_stmt (bb, &gsi);
      else
	/* If not eliminating, make all not already available defs
	   available.  */
	FOR_EACH_SSA_TREE_OPERAND (op, gsi_stmt (gsi), i, SSA_OP_DEF)
	  if (! avail.eliminate_avail (bb, op))
	    avail.eliminate_push_avail (bb, op);
    }

  /* Eliminate in destination PHI arguments.  Always substitute in dest
     PHIs, even for non-executable edges.  This handles region
     exits PHIs.  */
  if (!iterate && eliminate)
    FOR_EACH_EDGE (e, ei, bb->succs)
      for (gphi_iterator gsi = gsi_start_phis (e->dest);
	   !gsi_end_p (gsi); gsi_next (&gsi))
	{
	  gphi *phi = gsi.phi ();
	  use_operand_p use_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e);
	  tree arg = USE_FROM_PTR (use_p);
	  if (TREE_CODE (arg) != SSA_NAME
	      || virtual_operand_p (arg))
	    continue;
	  tree sprime;
	  if (SSA_NAME_IS_DEFAULT_DEF (arg))
	    {
	      sprime = SSA_VAL (arg);
	      gcc_assert (TREE_CODE (sprime) != SSA_NAME
			  || SSA_NAME_IS_DEFAULT_DEF (sprime));
	    }
	  else
	    /* Look for sth available at the definition block of the argument.
	       This avoids inconsistencies between availability there which
	       decides if the stmt can be removed and availability at the
	       use site.  The SSA property ensures that things available
	       at the definition are also available at uses.  */
	    sprime = avail.eliminate_avail (gimple_bb (SSA_NAME_DEF_STMT (arg)),
					    arg);
	  if (sprime
	      && sprime != arg
	      && may_propagate_copy (arg, sprime))
	    propagate_value (use_p, sprime);
	}

  vn_context_bb = NULL;
  return todo;
}

/* Unwind state per basic-block.  */

struct unwind_state
{
  /* Times this block has been visited.  */
  unsigned visited;
  /* Whether to handle this as iteration point or whether to treat
     incoming backedge PHI values as varying.  */
  bool iterate;
  /* Maximum RPO index this block is reachable from.  */
  int max_rpo;
  /* Unwind state.  */
  void *ob_top;
  vn_reference_t ref_top;
  vn_phi_t phi_top;
  vn_nary_op_t nary_top;
};

/* Unwind the RPO VN state for iteration.  */

static void
do_unwind (unwind_state *to, int rpo_idx, rpo_elim &avail, int *bb_to_rpo)
{
  gcc_assert (to->iterate);
  for (; last_inserted_nary != to->nary_top;
       last_inserted_nary = last_inserted_nary->next)
    {
      vn_nary_op_t *slot;
      slot = valid_info->nary->find_slot_with_hash
	(last_inserted_nary, last_inserted_nary->hashcode, NO_INSERT);
      /* Predication causes the need to restore previous state.  */
      if ((*slot)->unwind_to)
	*slot = (*slot)->unwind_to;
      else
	valid_info->nary->clear_slot (slot);
    }
  for (; last_inserted_phi != to->phi_top;
       last_inserted_phi = last_inserted_phi->next)
    {
      vn_phi_t *slot;
      slot = valid_info->phis->find_slot_with_hash
	(last_inserted_phi, last_inserted_phi->hashcode, NO_INSERT);
      valid_info->phis->clear_slot (slot);
    }
  for (; last_inserted_ref != to->ref_top;
       last_inserted_ref = last_inserted_ref->next)
    {
      vn_reference_t *slot;
      slot = valid_info->references->find_slot_with_hash
	(last_inserted_ref, last_inserted_ref->hashcode, NO_INSERT);
      (*slot)->operands.release ();
      valid_info->references->clear_slot (slot);
    }
  obstack_free (&vn_tables_obstack, to->ob_top);

  /* Prune [rpo_idx, ] from avail.  */
  /* ???  This is O(number-of-values-in-region) which is
     O(region-size) rather than O(iteration-piece).  */
  for (hash_table<vn_ssa_aux_hasher>::iterator i = vn_ssa_aux_hash->begin ();
       i != vn_ssa_aux_hash->end (); ++i)
    {
      while ((*i)->avail)
	{
	  if (bb_to_rpo[(*i)->avail->location] < rpo_idx)
	    break;
	  vn_avail *av = (*i)->avail;
	  (*i)->avail = (*i)->avail->next;
	  av->next = avail.m_avail_freelist;
	  avail.m_avail_freelist = av;
	}
    }
}

/* Do VN on a SEME region specified by ENTRY and EXIT_BBS in FN.
   If ITERATE is true then treat backedges optimistically as not
   executed and iterate.  If ELIMINATE is true then perform
   elimination, otherwise leave that to the caller.  */

static unsigned
do_rpo_vn (function *fn, edge entry, bitmap exit_bbs,
	   bool iterate, bool eliminate)
{
  unsigned todo = 0;

  /* We currently do not support region-based iteration when
     elimination is requested.  */
  gcc_assert (!entry || !iterate || !eliminate);
  /* When iterating we need loop info up-to-date.  */
  gcc_assert (!iterate || !loops_state_satisfies_p (LOOPS_NEED_FIXUP));

  bool do_region = entry != NULL;
  if (!do_region)
    {
      entry = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (fn));
      exit_bbs = BITMAP_ALLOC (NULL);
      bitmap_set_bit (exit_bbs, EXIT_BLOCK);
    }

  /* Clear EDGE_DFS_BACK on "all" entry edges, RPO order compute will
     re-mark those that are contained in the region.  */
  edge_iterator ei;
  edge e;
  FOR_EACH_EDGE (e, ei, entry->dest->preds)
    e->flags &= ~EDGE_DFS_BACK;

  int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (fn) - NUM_FIXED_BLOCKS);
  int n = rev_post_order_and_mark_dfs_back_seme
    (fn, entry, exit_bbs, !loops_state_satisfies_p (LOOPS_NEED_FIXUP), rpo);
  /* rev_post_order_and_mark_dfs_back_seme fills RPO in reverse order.  */
  for (int i = 0; i < n / 2; ++i)
    std::swap (rpo[i], rpo[n-i-1]);

  if (!do_region)
    BITMAP_FREE (exit_bbs);

  /* If there are any non-DFS_BACK edges into entry->dest skip
     processing PHI nodes for that block.  This supports
     value-numbering loop bodies w/o the actual loop.  */
  FOR_EACH_EDGE (e, ei, entry->dest->preds)
    if (e != entry
	&& !(e->flags & EDGE_DFS_BACK))
      break;
  bool skip_entry_phis = e != NULL;
  if (skip_entry_phis && dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "Region does not contain all edges into "
	     "the entry block, skipping its PHIs.\n");

  int *bb_to_rpo = XNEWVEC (int, last_basic_block_for_fn (fn));
  for (int i = 0; i < n; ++i)
    bb_to_rpo[rpo[i]] = i;

  unwind_state *rpo_state = XNEWVEC (unwind_state, n);

  rpo_elim avail (entry->dest);
  rpo_avail = &avail;

  /* Verify we have no extra entries into the region.  */
  if (flag_checking && do_region)
    {
      auto_bb_flag bb_in_region (fn);
      for (int i = 0; i < n; ++i)
	{
	  basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
	  bb->flags |= bb_in_region;
	}
      /* We can't merge the first two loops because we cannot rely
         on EDGE_DFS_BACK for edges not within the region.  But if
	 we decide to always have the bb_in_region flag we can
	 do the checking during the RPO walk itself (but then it's
	 also easy to handle MEME conservatively).  */
      for (int i = 0; i < n; ++i)
	{
	  basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
	  edge e;
	  edge_iterator ei;
	  FOR_EACH_EDGE (e, ei, bb->preds)
	    gcc_assert (e == entry
			|| (skip_entry_phis && bb == entry->dest)
			|| (e->src->flags & bb_in_region));
	}
      for (int i = 0; i < n; ++i)
	{
	  basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
	  bb->flags &= ~bb_in_region;
	}
    }

  /* Create the VN state.  For the initial size of the various hashtables
     use a heuristic based on region size and number of SSA names.  */
  unsigned region_size = (((unsigned HOST_WIDE_INT)n * num_ssa_names)
			  / (n_basic_blocks_for_fn (fn) - NUM_FIXED_BLOCKS));
  VN_TOP = create_tmp_var_raw (void_type_node, "vn_top");
  next_value_id = 1;

  vn_ssa_aux_hash = new hash_table <vn_ssa_aux_hasher> (region_size * 2);
  gcc_obstack_init (&vn_ssa_aux_obstack);

  gcc_obstack_init (&vn_tables_obstack);
  gcc_obstack_init (&vn_tables_insert_obstack);
  valid_info = XCNEW (struct vn_tables_s);
  allocate_vn_table (valid_info, region_size);
  last_inserted_ref = NULL;
  last_inserted_phi = NULL;
  last_inserted_nary = NULL;

  vn_valueize = rpo_vn_valueize;

  /* Initialize the unwind state and edge/BB executable state.  */
  bool need_max_rpo_iterate = false;
  for (int i = 0; i < n; ++i)
    {
      basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
      rpo_state[i].visited = 0;
      rpo_state[i].max_rpo = i;
      bb->flags &= ~BB_EXECUTABLE;
      bool has_backedges = false;
      edge e;
      edge_iterator ei;
      FOR_EACH_EDGE (e, ei, bb->preds)
	{
	  if (e->flags & EDGE_DFS_BACK)
	    has_backedges = true;
	  e->flags &= ~EDGE_EXECUTABLE;
	  if (iterate || e == entry || (skip_entry_phis && bb == entry->dest))
	    continue;
	  if (bb_to_rpo[e->src->index] > i)
	    {
	      rpo_state[i].max_rpo = MAX (rpo_state[i].max_rpo,
					  bb_to_rpo[e->src->index]);
	      need_max_rpo_iterate = true;
	    }
	  else
	    rpo_state[i].max_rpo
	      = MAX (rpo_state[i].max_rpo,
		     rpo_state[bb_to_rpo[e->src->index]].max_rpo);
	}
      rpo_state[i].iterate = iterate && has_backedges;
    }
  entry->flags |= EDGE_EXECUTABLE;
  entry->dest->flags |= BB_EXECUTABLE;

  /* When there are irreducible regions the simplistic max_rpo computation
     above for the case of backedges doesn't work and we need to iterate
     until there are no more changes.  */
  unsigned nit = 0;
  while (need_max_rpo_iterate)
    {
      nit++;
      need_max_rpo_iterate = false;
      for (int i = 0; i < n; ++i)
	{
	  basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
	  edge e;
	  edge_iterator ei;
	  FOR_EACH_EDGE (e, ei, bb->preds)
	    {
	      if (e == entry || (skip_entry_phis && bb == entry->dest))
		continue;
	      int max_rpo = MAX (rpo_state[i].max_rpo,
				 rpo_state[bb_to_rpo[e->src->index]].max_rpo);
	      if (rpo_state[i].max_rpo != max_rpo)
		{
		  rpo_state[i].max_rpo = max_rpo;
		  need_max_rpo_iterate = true;
		}
	    }
	}
    }
  statistics_histogram_event (cfun, "RPO max_rpo iterations", nit);

  /* As heuristic to improve compile-time we handle only the N innermost
     loops and the outermost one optimistically.  */
  if (iterate)
    {
      loop_p loop;
      unsigned max_depth = param_rpo_vn_max_loop_depth;
      FOR_EACH_LOOP (loop, LI_ONLY_INNERMOST)
	if (loop_depth (loop) > max_depth)
	  for (unsigned i = 2;
	       i < loop_depth (loop) - max_depth; ++i)
	    {
	      basic_block header = superloop_at_depth (loop, i)->header;
	      bool non_latch_backedge = false;
	      edge e;
	      edge_iterator ei;
	      FOR_EACH_EDGE (e, ei, header->preds)
		if (e->flags & EDGE_DFS_BACK)
		  {
		    /* There can be a non-latch backedge into the header
		       which is part of an outer irreducible region.  We
		       cannot avoid iterating this block then.  */
		    if (!dominated_by_p (CDI_DOMINATORS,
					 e->src, e->dest))
		      {
			if (dump_file && (dump_flags & TDF_DETAILS))
			  fprintf (dump_file, "non-latch backedge %d -> %d "
				   "forces iteration of loop %d\n",
				   e->src->index, e->dest->index, loop->num);
			non_latch_backedge = true;
		      }
		    else
		      e->flags |= EDGE_EXECUTABLE;
		  }
	      rpo_state[bb_to_rpo[header->index]].iterate = non_latch_backedge;
	    }
    }

  uint64_t nblk = 0;
  int idx = 0;
  if (iterate)
    /* Go and process all blocks, iterating as necessary.  */
    do
      {
	basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[idx]);

	/* If the block has incoming backedges remember unwind state.  This
	   is required even for non-executable blocks since in irreducible
	   regions we might reach them via the backedge and re-start iterating
	   from there.
	   Note we can individually mark blocks with incoming backedges to
	   not iterate where we then handle PHIs conservatively.  We do that
	   heuristically to reduce compile-time for degenerate cases.  */
	if (rpo_state[idx].iterate)
	  {
	    rpo_state[idx].ob_top = obstack_alloc (&vn_tables_obstack, 0);
	    rpo_state[idx].ref_top = last_inserted_ref;
	    rpo_state[idx].phi_top = last_inserted_phi;
	    rpo_state[idx].nary_top = last_inserted_nary;
	  }

	if (!(bb->flags & BB_EXECUTABLE))
	  {
	    if (dump_file && (dump_flags & TDF_DETAILS))
	      fprintf (dump_file, "Block %d: BB%d found not executable\n",
		       idx, bb->index);
	    idx++;
	    continue;
	  }

	if (dump_file && (dump_flags & TDF_DETAILS))
	  fprintf (dump_file, "Processing block %d: BB%d\n", idx, bb->index);
	nblk++;
	todo |= process_bb (avail, bb,
			    rpo_state[idx].visited != 0,
			    rpo_state[idx].iterate,
			    iterate, eliminate, do_region, exit_bbs, false);
	rpo_state[idx].visited++;

	/* Verify if changed values flow over executable outgoing backedges
	   and those change destination PHI values (that's the thing we
	   can easily verify).  Reduce over all such edges to the farthest
	   away PHI.  */
	int iterate_to = -1;
	edge_iterator ei;
	edge e;
	FOR_EACH_EDGE (e, ei, bb->succs)
	  if ((e->flags & (EDGE_DFS_BACK|EDGE_EXECUTABLE))
	      == (EDGE_DFS_BACK|EDGE_EXECUTABLE)
	      && rpo_state[bb_to_rpo[e->dest->index]].iterate)
	    {
	      int destidx = bb_to_rpo[e->dest->index];
	      if (!rpo_state[destidx].visited)
		{
		  if (dump_file && (dump_flags & TDF_DETAILS))
		    fprintf (dump_file, "Unvisited destination %d\n",
			     e->dest->index);
		  if (iterate_to == -1 || destidx < iterate_to)
		    iterate_to = destidx;
		  continue;
		}
	      if (dump_file && (dump_flags & TDF_DETAILS))
		fprintf (dump_file, "Looking for changed values of backedge"
			 " %d->%d destination PHIs\n",
			 e->src->index, e->dest->index);
	      vn_context_bb = e->dest;
	      gphi_iterator gsi;
	      for (gsi = gsi_start_phis (e->dest);
		   !gsi_end_p (gsi); gsi_next (&gsi))
		{
		  bool inserted = false;
		  /* While we'd ideally just iterate on value changes
		     we CSE PHIs and do that even across basic-block
		     boundaries.  So even hashtable state changes can
		     be important (which is roughly equivalent to
		     PHI argument value changes).  To not excessively
		     iterate because of that we track whether a PHI
		     was CSEd to with GF_PLF_1.  */
		  bool phival_changed;
		  if ((phival_changed = visit_phi (gsi.phi (),
						   &inserted, false))
		      || (inserted && gimple_plf (gsi.phi (), GF_PLF_1)))
		    {
		      if (!phival_changed
			  && dump_file && (dump_flags & TDF_DETAILS))
			fprintf (dump_file, "PHI was CSEd and hashtable "
				 "state (changed)\n");
		      if (iterate_to == -1 || destidx < iterate_to)
			iterate_to = destidx;
		      break;
		    }
		}
	      vn_context_bb = NULL;
	    }
	if (iterate_to != -1)
	  {
	    do_unwind (&rpo_state[iterate_to], iterate_to, avail, bb_to_rpo);
	    idx = iterate_to;
	    if (dump_file && (dump_flags & TDF_DETAILS))
	      fprintf (dump_file, "Iterating to %d BB%d\n",
		       iterate_to, rpo[iterate_to]);
	    continue;
	  }

	idx++;
      }
    while (idx < n);

  else /* !iterate */
    {
      /* Process all blocks greedily with a worklist that enforces RPO
         processing of reachable blocks.  */
      auto_bitmap worklist;
      bitmap_set_bit (worklist, 0);
      while (!bitmap_empty_p (worklist))
	{
	  int idx = bitmap_first_set_bit (worklist);
	  bitmap_clear_bit (worklist, idx);
	  basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[idx]);
	  gcc_assert ((bb->flags & BB_EXECUTABLE)
		      && !rpo_state[idx].visited);

	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file, "Processing block %d: BB%d\n", idx, bb->index);

	  /* When we run into predecessor edges where we cannot trust its
	     executable state mark them executable so PHI processing will
	     be conservative.
	     ???  Do we need to force arguments flowing over that edge
	     to be varying or will they even always be?  */
	  edge_iterator ei;
	  edge e;
	  FOR_EACH_EDGE (e, ei, bb->preds)
	    if (!(e->flags & EDGE_EXECUTABLE)
		&& (bb == entry->dest
		    || (!rpo_state[bb_to_rpo[e->src->index]].visited
			&& (rpo_state[bb_to_rpo[e->src->index]].max_rpo
			    >= (int)idx))))
	      {
		if (dump_file && (dump_flags & TDF_DETAILS))
		  fprintf (dump_file, "Cannot trust state of predecessor "
			   "edge %d -> %d, marking executable\n",
			   e->src->index, e->dest->index);
		e->flags |= EDGE_EXECUTABLE;
	      }

	  nblk++;
	  todo |= process_bb (avail, bb, false, false, false, eliminate,
			      do_region, exit_bbs,
			      skip_entry_phis && bb == entry->dest);
	  rpo_state[idx].visited++;

	  FOR_EACH_EDGE (e, ei, bb->succs)
	    if ((e->flags & EDGE_EXECUTABLE)
		&& e->dest->index != EXIT_BLOCK
		&& (!do_region || !bitmap_bit_p (exit_bbs, e->dest->index))
		&& !rpo_state[bb_to_rpo[e->dest->index]].visited)
	      bitmap_set_bit (worklist, bb_to_rpo[e->dest->index]);
	}
    }

  /* If statistics or dump file active.  */
  int nex = 0;
  unsigned max_visited = 1;
  for (int i = 0; i < n; ++i)
    {
      basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
      if (bb->flags & BB_EXECUTABLE)
	nex++;
      statistics_histogram_event (cfun, "RPO block visited times",
				  rpo_state[i].visited);
      if (rpo_state[i].visited > max_visited)
	max_visited = rpo_state[i].visited;
    }
  unsigned nvalues = 0, navail = 0;
  for (hash_table<vn_ssa_aux_hasher>::iterator i = vn_ssa_aux_hash->begin ();
       i != vn_ssa_aux_hash->end (); ++i)
    {
      nvalues++;
      vn_avail *av = (*i)->avail;
      while (av)
	{
	  navail++;
	  av = av->next;
	}
    }
  statistics_counter_event (cfun, "RPO blocks", n);
  statistics_counter_event (cfun, "RPO blocks visited", nblk);
  statistics_counter_event (cfun, "RPO blocks executable", nex);
  statistics_histogram_event (cfun, "RPO iterations", 10*nblk / nex);
  statistics_histogram_event (cfun, "RPO num values", nvalues);
  statistics_histogram_event (cfun, "RPO num avail", navail);
  statistics_histogram_event (cfun, "RPO num lattice",
			      vn_ssa_aux_hash->elements ());
  if (dump_file && (dump_flags & (TDF_DETAILS|TDF_STATS)))
    {
      fprintf (dump_file, "RPO iteration over %d blocks visited %" PRIu64
	       " blocks in total discovering %d executable blocks iterating "
	       "%d.%d times, a block was visited max. %u times\n",
	       n, nblk, nex,
	       (int)((10*nblk / nex)/10), (int)((10*nblk / nex)%10),
	       max_visited);
      fprintf (dump_file, "RPO tracked %d values available at %d locations "
	       "and %" PRIu64 " lattice elements\n",
	       nvalues, navail, (uint64_t) vn_ssa_aux_hash->elements ());
    }

  if (eliminate)
    {
      /* When !iterate we already performed elimination during the RPO
         walk.  */
      if (iterate)
	{
	  /* Elimination for region-based VN needs to be done within the
	     RPO walk.  */
	  gcc_assert (! do_region);
	  /* Note we can't use avail.walk here because that gets confused
	     by the existing availability and it will be less efficient
	     as well.  */
	  todo |= eliminate_with_rpo_vn (NULL);
	}
      else
	todo |= avail.eliminate_cleanup (do_region);
    }

  vn_valueize = NULL;
  rpo_avail = NULL;

  XDELETEVEC (bb_to_rpo);
  XDELETEVEC (rpo);
  XDELETEVEC (rpo_state);

  return todo;
}

/* Region-based entry for RPO VN.  Performs value-numbering and elimination
   on the SEME region specified by ENTRY and EXIT_BBS.  If ENTRY is not
   the only edge into the region at ENTRY->dest PHI nodes in ENTRY->dest
   are not considered.  */

unsigned
do_rpo_vn (function *fn, edge entry, bitmap exit_bbs)
{
  default_vn_walk_kind = VN_WALKREWRITE;
  unsigned todo = do_rpo_vn (fn, entry, exit_bbs, false, true);
  free_rpo_vn ();
  return todo;
}


namespace {

const pass_data pass_data_fre =
{
  GIMPLE_PASS, /* type */
  "fre", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_TREE_FRE, /* tv_id */
  ( PROP_cfg | PROP_ssa ), /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_fre : public gimple_opt_pass
{
public:
  pass_fre (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_fre, ctxt), may_iterate (true)
  {}

  /* opt_pass methods: */
  opt_pass * clone () { return new pass_fre (m_ctxt); }
  void set_pass_param (unsigned int n, bool param)
    {
      gcc_assert (n == 0);
      may_iterate = param;
    }
  virtual bool gate (function *)
    {
      return flag_tree_fre != 0 && (may_iterate || optimize > 1);
    }
  virtual unsigned int execute (function *);

private:
  bool may_iterate;
}; // class pass_fre

unsigned int
pass_fre::execute (function *fun)
{
  unsigned todo = 0;

  /* At -O[1g] use the cheap non-iterating mode.  */
  bool iterate_p = may_iterate && (optimize > 1);
  calculate_dominance_info (CDI_DOMINATORS);
  if (iterate_p)
    loop_optimizer_init (AVOID_CFG_MODIFICATIONS);

  default_vn_walk_kind = VN_WALKREWRITE;
  todo = do_rpo_vn (fun, NULL, NULL, iterate_p, true);
  free_rpo_vn ();

  if (iterate_p)
    loop_optimizer_finalize ();

  /* For late FRE after IVOPTs and unrolling, see if we can
     remove some TREE_ADDRESSABLE and rewrite stuff into SSA.  */
  if (!may_iterate)
    todo |= TODO_update_address_taken;

  return todo;
}

} // anon namespace

gimple_opt_pass *
make_pass_fre (gcc::context *ctxt)
{
  return new pass_fre (ctxt);
}

#undef BB_EXECUTABLE
