/* Full and partial redundancy elimination and code hoisting on SSA GIMPLE.
   Copyright (C) 2001-2019 Free Software Foundation, Inc.
   Contributed by Daniel Berlin <dan@dberlin.org> and Steven Bosscher
   <stevenb@suse.de>

This file is part of GCC.

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

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

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

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "predict.h"
#include "alloc-pool.h"
#include "tree-pass.h"
#include "ssa.h"
#include "cgraph.h"
#include "gimple-pretty-print.h"
#include "fold-const.h"
#include "cfganal.h"
#include "gimple-fold.h"
#include "tree-eh.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "tree-cfg.h"
#include "tree-into-ssa.h"
#include "tree-dfa.h"
#include "tree-ssa.h"
#include "cfgloop.h"
#include "tree-ssa-sccvn.h"
#include "tree-scalar-evolution.h"
#include "params.h"
#include "dbgcnt.h"
#include "domwalk.h"
#include "tree-ssa-propagate.h"
#include "tree-ssa-dce.h"
#include "tree-cfgcleanup.h"
#include "alias.h"

/* Even though this file is called tree-ssa-pre.c, we actually
   implement a bit more than just PRE here.  All of them piggy-back
   on GVN which is implemented in tree-ssa-sccvn.c.

     1. Full Redundancy Elimination (FRE)
	This is the elimination phase of GVN.

     2. Partial Redundancy Elimination (PRE)
	This is adds computation of AVAIL_OUT and ANTIC_IN and
	doing expression insertion to form GVN-PRE.

     3. Code hoisting
	This optimization uses the ANTIC_IN sets computed for PRE
	to move expressions further up than PRE would do, to make
	multiple computations of the same value fully redundant.
	This pass is explained below (after the explanation of the
	basic algorithm for PRE).
*/

/* TODO:

   1. Avail sets can be shared by making an avail_find_leader that
      walks up the dominator tree and looks in those avail sets.
      This might affect code optimality, it's unclear right now.
      Currently the AVAIL_OUT sets are the remaining quadraticness in
      memory of GVN-PRE.
   2. Strength reduction can be performed by anticipating expressions
      we can repair later on.
   3. We can do back-substitution or smarter value numbering to catch
      commutative expressions split up over multiple statements.
*/

/* For ease of terminology, "expression node" in the below refers to
   every expression node but GIMPLE_ASSIGN, because GIMPLE_ASSIGNs
   represent the actual statement containing the expressions we care about,
   and we cache the value number by putting it in the expression.  */

/* Basic algorithm for Partial Redundancy Elimination:

   First we walk the statements to generate the AVAIL sets, the
   EXP_GEN sets, and the tmp_gen sets.  EXP_GEN sets represent the
   generation of values/expressions by a given block.  We use them
   when computing the ANTIC sets.  The AVAIL sets consist of
   SSA_NAME's that represent values, so we know what values are
   available in what blocks.  AVAIL is a forward dataflow problem.  In
   SSA, values are never killed, so we don't need a kill set, or a
   fixpoint iteration, in order to calculate the AVAIL sets.  In
   traditional parlance, AVAIL sets tell us the downsafety of the
   expressions/values.

   Next, we generate the ANTIC sets.  These sets represent the
   anticipatable expressions.  ANTIC is a backwards dataflow
   problem.  An expression is anticipatable in a given block if it could
   be generated in that block.  This means that if we had to perform
   an insertion in that block, of the value of that expression, we
   could.  Calculating the ANTIC sets requires phi translation of
   expressions, because the flow goes backwards through phis.  We must
   iterate to a fixpoint of the ANTIC sets, because we have a kill
   set.  Even in SSA form, values are not live over the entire
   function, only from their definition point onwards.  So we have to
   remove values from the ANTIC set once we go past the definition
   point of the leaders that make them up.
   compute_antic/compute_antic_aux performs this computation.

   Third, we perform insertions to make partially redundant
   expressions fully redundant.

   An expression is partially redundant (excluding partial
   anticipation) if:

   1. It is AVAIL in some, but not all, of the predecessors of a
      given block.
   2. It is ANTIC in all the predecessors.

   In order to make it fully redundant, we insert the expression into
   the predecessors where it is not available, but is ANTIC.

   When optimizing for size, we only eliminate the partial redundancy
   if we need to insert in only one predecessor.  This avoids almost
   completely the code size increase that PRE usually causes.

   For the partial anticipation case, we only perform insertion if it
   is partially anticipated in some block, and fully available in all
   of the predecessors.

   do_pre_regular_insertion/do_pre_partial_partial_insertion
   performs these steps, driven by insert/insert_aux.

   Fourth, we eliminate fully redundant expressions.
   This is a simple statement walk that replaces redundant
   calculations with the now available values.  */

/* Basic algorithm for Code Hoisting:

   Code hoisting is: Moving value computations up in the control flow
   graph to make multiple copies redundant.  Typically this is a size
   optimization, but there are cases where it also is helpful for speed.

   A simple code hoisting algorithm is implemented that piggy-backs on
   the PRE infrastructure.  For code hoisting, we have to know ANTIC_OUT
   which is effectively ANTIC_IN - AVAIL_OUT.  The latter two have to be
   computed for PRE, and we can use them to perform a limited version of
   code hoisting, too.

   For the purpose of this implementation, a value is hoistable to a basic
   block B if the following properties are met:

   1. The value is in ANTIC_IN(B) -- the value will be computed on all
      paths from B to function exit and it can be computed in B);

   2. The value is not in AVAIL_OUT(B) -- there would be no need to
      compute the value again and make it available twice;

   3. All successors of B are dominated by B -- makes sure that inserting
      a computation of the value in B will make the remaining
      computations fully redundant;

   4. At least one successor has the value in AVAIL_OUT -- to avoid
      hoisting values up too far;

   5. There are at least two successors of B -- hoisting in straight
      line code is pointless.

   The third condition is not strictly necessary, but it would complicate
   the hoisting pass a lot.  In fact, I don't know of any code hoisting
   algorithm that does not have this requirement.  Fortunately, experiments
   have show that most candidate hoistable values are in regions that meet
   this condition (e.g. diamond-shape regions).

   The forth condition is necessary to avoid hoisting things up too far
   away from the uses of the value.  Nothing else limits the algorithm
   from hoisting everything up as far as ANTIC_IN allows.  Experiments
   with SPEC and CSiBE have shown that hoisting up too far results in more
   spilling, less benefits for code size, and worse benchmark scores.
   Fortunately, in practice most of the interesting hoisting opportunities
   are caught despite this limitation.

   For hoistable values that meet all conditions, expressions are inserted
   to make the calculation of the hoistable value fully redundant.  We
   perform code hoisting insertions after each round of PRE insertions,
   because code hoisting never exposes new PRE opportunities, but PRE can
   create new code hoisting opportunities.

   The code hoisting algorithm is implemented in do_hoist_insert, driven
   by insert/insert_aux.  */

/* Representations of value numbers:

   Value numbers are represented by a representative SSA_NAME.  We
   will create fake SSA_NAME's in situations where we need a
   representative but do not have one (because it is a complex
   expression).  In order to facilitate storing the value numbers in
   bitmaps, and keep the number of wasted SSA_NAME's down, we also
   associate a value_id with each value number, and create full blown
   ssa_name's only where we actually need them (IE in operands of
   existing expressions).

   Theoretically you could replace all the value_id's with
   SSA_NAME_VERSION, but this would allocate a large number of
   SSA_NAME's (which are each > 30 bytes) just to get a 4 byte number.
   It would also require an additional indirection at each point we
   use the value id.  */

/* Representation of expressions on value numbers:

   Expressions consisting of value numbers are represented the same
   way as our VN internally represents them, with an additional
   "pre_expr" wrapping around them in order to facilitate storing all
   of the expressions in the same sets.  */

/* Representation of sets:

   The dataflow sets do not need to be sorted in any particular order
   for the majority of their lifetime, are simply represented as two
   bitmaps, one that keeps track of values present in the set, and one
   that keeps track of expressions present in the set.

   When we need them in topological order, we produce it on demand by
   transforming the bitmap into an array and sorting it into topo
   order.  */

/* Type of expression, used to know which member of the PRE_EXPR union
   is valid.  */

enum pre_expr_kind
{
    NAME,
    NARY,
    REFERENCE,
    CONSTANT
};

union pre_expr_union
{
  tree name;
  tree constant;
  vn_nary_op_t nary;
  vn_reference_t reference;
};

typedef struct pre_expr_d : nofree_ptr_hash <pre_expr_d>
{
  enum pre_expr_kind kind;
  unsigned int id;
  pre_expr_union u;

  /* hash_table support.  */
  static inline hashval_t hash (const pre_expr_d *);
  static inline int equal (const pre_expr_d *, const pre_expr_d *);
} *pre_expr;

#define PRE_EXPR_NAME(e) (e)->u.name
#define PRE_EXPR_NARY(e) (e)->u.nary
#define PRE_EXPR_REFERENCE(e) (e)->u.reference
#define PRE_EXPR_CONSTANT(e) (e)->u.constant

/* Compare E1 and E1 for equality.  */

inline int
pre_expr_d::equal (const pre_expr_d *e1, const pre_expr_d *e2)
{
  if (e1->kind != e2->kind)
    return false;

  switch (e1->kind)
    {
    case CONSTANT:
      return vn_constant_eq_with_type (PRE_EXPR_CONSTANT (e1),
				       PRE_EXPR_CONSTANT (e2));
    case NAME:
      return PRE_EXPR_NAME (e1) == PRE_EXPR_NAME (e2);
    case NARY:
      return vn_nary_op_eq (PRE_EXPR_NARY (e1), PRE_EXPR_NARY (e2));
    case REFERENCE:
      return vn_reference_eq (PRE_EXPR_REFERENCE (e1),
			      PRE_EXPR_REFERENCE (e2));
    default:
      gcc_unreachable ();
    }
}

/* Hash E.  */

inline hashval_t
pre_expr_d::hash (const pre_expr_d *e)
{
  switch (e->kind)
    {
    case CONSTANT:
      return vn_hash_constant_with_type (PRE_EXPR_CONSTANT (e));
    case NAME:
      return SSA_NAME_VERSION (PRE_EXPR_NAME (e));
    case NARY:
      return PRE_EXPR_NARY (e)->hashcode;
    case REFERENCE:
      return PRE_EXPR_REFERENCE (e)->hashcode;
    default:
      gcc_unreachable ();
    }
}

/* Next global expression id number.  */
static unsigned int next_expression_id;

/* Mapping from expression to id number we can use in bitmap sets.  */
static vec<pre_expr> expressions;
static hash_table<pre_expr_d> *expression_to_id;
static vec<unsigned> name_to_id;

/* Allocate an expression id for EXPR.  */

static inline unsigned int
alloc_expression_id (pre_expr expr)
{
  struct pre_expr_d **slot;
  /* Make sure we won't overflow. */
  gcc_assert (next_expression_id + 1 > next_expression_id);
  expr->id = next_expression_id++;
  expressions.safe_push (expr);
  if (expr->kind == NAME)
    {
      unsigned version = SSA_NAME_VERSION (PRE_EXPR_NAME (expr));
      /* vec::safe_grow_cleared allocates no headroom.  Avoid frequent
	 re-allocations by using vec::reserve upfront.  */
      unsigned old_len = name_to_id.length ();
      name_to_id.reserve (num_ssa_names - old_len);
      name_to_id.quick_grow_cleared (num_ssa_names);
      gcc_assert (name_to_id[version] == 0);
      name_to_id[version] = expr->id;
    }
  else
    {
      slot = expression_to_id->find_slot (expr, INSERT);
      gcc_assert (!*slot);
      *slot = expr;
    }
  return next_expression_id - 1;
}

/* Return the expression id for tree EXPR.  */

static inline unsigned int
get_expression_id (const pre_expr expr)
{
  return expr->id;
}

static inline unsigned int
lookup_expression_id (const pre_expr expr)
{
  struct pre_expr_d **slot;

  if (expr->kind == NAME)
    {
      unsigned version = SSA_NAME_VERSION (PRE_EXPR_NAME (expr));
      if (name_to_id.length () <= version)
	return 0;
      return name_to_id[version];
    }
  else
    {
      slot = expression_to_id->find_slot (expr, NO_INSERT);
      if (!slot)
	return 0;
      return ((pre_expr)*slot)->id;
    }
}

/* Return the existing expression id for EXPR, or create one if one
   does not exist yet.  */

static inline unsigned int
get_or_alloc_expression_id (pre_expr expr)
{
  unsigned int id = lookup_expression_id (expr);
  if (id == 0)
    return alloc_expression_id (expr);
  return expr->id = id;
}

/* Return the expression that has expression id ID */

static inline pre_expr
expression_for_id (unsigned int id)
{
  return expressions[id];
}

static object_allocator<pre_expr_d> pre_expr_pool ("pre_expr nodes");

/* Given an SSA_NAME NAME, get or create a pre_expr to represent it.  */

static pre_expr
get_or_alloc_expr_for_name (tree name)
{
  struct pre_expr_d expr;
  pre_expr result;
  unsigned int result_id;

  expr.kind = NAME;
  expr.id = 0;
  PRE_EXPR_NAME (&expr) = name;
  result_id = lookup_expression_id (&expr);
  if (result_id != 0)
    return expression_for_id (result_id);

  result = pre_expr_pool.allocate ();
  result->kind = NAME;
  PRE_EXPR_NAME (result) = name;
  alloc_expression_id (result);
  return result;
}

/* An unordered bitmap set.  One bitmap tracks values, the other,
   expressions.  */
typedef struct bitmap_set
{
  bitmap_head expressions;
  bitmap_head values;
} *bitmap_set_t;

#define FOR_EACH_EXPR_ID_IN_SET(set, id, bi)		\
  EXECUTE_IF_SET_IN_BITMAP (&(set)->expressions, 0, (id), (bi))

#define FOR_EACH_VALUE_ID_IN_SET(set, id, bi)		\
  EXECUTE_IF_SET_IN_BITMAP (&(set)->values, 0, (id), (bi))

/* Mapping from value id to expressions with that value_id.  */
static vec<bitmap> value_expressions;

/* Sets that we need to keep track of.  */
typedef struct bb_bitmap_sets
{
  /* The EXP_GEN set, which represents expressions/values generated in
     a basic block.  */
  bitmap_set_t exp_gen;

  /* The PHI_GEN set, which represents PHI results generated in a
     basic block.  */
  bitmap_set_t phi_gen;

  /* The TMP_GEN set, which represents results/temporaries generated
     in a basic block. IE the LHS of an expression.  */
  bitmap_set_t tmp_gen;

  /* The AVAIL_OUT set, which represents which values are available in
     a given basic block.  */
  bitmap_set_t avail_out;

  /* The ANTIC_IN set, which represents which values are anticipatable
     in a given basic block.  */
  bitmap_set_t antic_in;

  /* The PA_IN set, which represents which values are
     partially anticipatable in a given basic block.  */
  bitmap_set_t pa_in;

  /* The NEW_SETS set, which is used during insertion to augment the
     AVAIL_OUT set of blocks with the new insertions performed during
     the current iteration.  */
  bitmap_set_t new_sets;

  /* A cache for value_dies_in_block_x.  */
  bitmap expr_dies;

  /* The live virtual operand on successor edges.  */
  tree vop_on_exit;

  /* True if we have visited this block during ANTIC calculation.  */
  unsigned int visited : 1;

  /* True when the block contains a call that might not return.  */
  unsigned int contains_may_not_return_call : 1;
} *bb_value_sets_t;

#define EXP_GEN(BB)	((bb_value_sets_t) ((BB)->aux))->exp_gen
#define PHI_GEN(BB)	((bb_value_sets_t) ((BB)->aux))->phi_gen
#define TMP_GEN(BB)	((bb_value_sets_t) ((BB)->aux))->tmp_gen
#define AVAIL_OUT(BB)	((bb_value_sets_t) ((BB)->aux))->avail_out
#define ANTIC_IN(BB)	((bb_value_sets_t) ((BB)->aux))->antic_in
#define PA_IN(BB)	((bb_value_sets_t) ((BB)->aux))->pa_in
#define NEW_SETS(BB)	((bb_value_sets_t) ((BB)->aux))->new_sets
#define EXPR_DIES(BB)	((bb_value_sets_t) ((BB)->aux))->expr_dies
#define BB_VISITED(BB)	((bb_value_sets_t) ((BB)->aux))->visited
#define BB_MAY_NOTRETURN(BB) ((bb_value_sets_t) ((BB)->aux))->contains_may_not_return_call
#define BB_LIVE_VOP_ON_EXIT(BB) ((bb_value_sets_t) ((BB)->aux))->vop_on_exit


/* This structure is used to keep track of statistics on what
   optimization PRE was able to perform.  */
static struct
{
  /* The number of new expressions/temporaries generated by PRE.  */
  int insertions;

  /* The number of inserts found due to partial anticipation  */
  int pa_insert;

  /* The number of inserts made for code hoisting.  */
  int hoist_insert;

  /* The number of new PHI nodes added by PRE.  */
  int phis;
} pre_stats;

static bool do_partial_partial;
static pre_expr bitmap_find_leader (bitmap_set_t, unsigned int);
static void bitmap_value_insert_into_set (bitmap_set_t, pre_expr);
static void bitmap_value_replace_in_set (bitmap_set_t, pre_expr);
static void bitmap_set_copy (bitmap_set_t, bitmap_set_t);
static bool bitmap_set_contains_value (bitmap_set_t, unsigned int);
static void bitmap_insert_into_set (bitmap_set_t, pre_expr);
static bitmap_set_t bitmap_set_new (void);
static tree create_expression_by_pieces (basic_block, pre_expr, gimple_seq *,
					 tree);
static tree find_or_generate_expression (basic_block, tree, gimple_seq *);
static unsigned int get_expr_value_id (pre_expr);

/* We can add and remove elements and entries to and from sets
   and hash tables, so we use alloc pools for them.  */

static object_allocator<bitmap_set> bitmap_set_pool ("Bitmap sets");
static bitmap_obstack grand_bitmap_obstack;

/* A three tuple {e, pred, v} used to cache phi translations in the
   phi_translate_table.  */

typedef struct expr_pred_trans_d : free_ptr_hash<expr_pred_trans_d>
{
  /* The expression.  */
  pre_expr e;

  /* The predecessor block along which we translated the expression.  */
  basic_block pred;

  /* The value that resulted from the translation.  */
  pre_expr v;

  /* The hashcode for the expression, pred pair. This is cached for
     speed reasons.  */
  hashval_t hashcode;

  /* hash_table support.  */
  static inline hashval_t hash (const expr_pred_trans_d *);
  static inline int equal (const expr_pred_trans_d *, const expr_pred_trans_d *);
} *expr_pred_trans_t;
typedef const struct expr_pred_trans_d *const_expr_pred_trans_t;

inline hashval_t
expr_pred_trans_d::hash (const expr_pred_trans_d *e)
{
  return e->hashcode;
}

inline int
expr_pred_trans_d::equal (const expr_pred_trans_d *ve1,
			  const expr_pred_trans_d *ve2)
{
  basic_block b1 = ve1->pred;
  basic_block b2 = ve2->pred;

  /* If they are not translations for the same basic block, they can't
     be equal.  */
  if (b1 != b2)
    return false;
  return pre_expr_d::equal (ve1->e, ve2->e);
}

/* The phi_translate_table caches phi translations for a given
   expression and predecessor.  */
static hash_table<expr_pred_trans_d> *phi_translate_table;

/* Add the tuple mapping from {expression E, basic block PRED} to
   the phi translation table and return whether it pre-existed.  */

static inline bool
phi_trans_add (expr_pred_trans_t *entry, pre_expr e, basic_block pred)
{
  expr_pred_trans_t *slot;
  expr_pred_trans_d tem;
  hashval_t hash = iterative_hash_hashval_t (pre_expr_d::hash (e),
					     pred->index);
  tem.e = e;
  tem.pred = pred;
  tem.hashcode = hash;
  slot = phi_translate_table->find_slot_with_hash (&tem, hash, INSERT);
  if (*slot)
    {
      *entry = *slot;
      return true;
    }

  *entry = *slot = XNEW (struct expr_pred_trans_d);
  (*entry)->e = e;
  (*entry)->pred = pred;
  (*entry)->hashcode = hash;
  return false;
}


/* Add expression E to the expression set of value id V.  */

static void
add_to_value (unsigned int v, pre_expr e)
{
  bitmap set;

  gcc_checking_assert (get_expr_value_id (e) == v);

  if (v >= value_expressions.length ())
    {
      value_expressions.safe_grow_cleared (v + 1);
    }

  set = value_expressions[v];
  if (!set)
    {
      set = BITMAP_ALLOC (&grand_bitmap_obstack);
      value_expressions[v] = set;
    }

  bitmap_set_bit (set, get_or_alloc_expression_id (e));
}

/* Create a new bitmap set and return it.  */

static bitmap_set_t
bitmap_set_new (void)
{
  bitmap_set_t ret = bitmap_set_pool.allocate ();
  bitmap_initialize (&ret->expressions, &grand_bitmap_obstack);
  bitmap_initialize (&ret->values, &grand_bitmap_obstack);
  return ret;
}

/* Return the value id for a PRE expression EXPR.  */

static unsigned int
get_expr_value_id (pre_expr expr)
{
  unsigned int id;
  switch (expr->kind)
    {
    case CONSTANT:
      id = get_constant_value_id (PRE_EXPR_CONSTANT (expr));
      break;
    case NAME:
      id = VN_INFO (PRE_EXPR_NAME (expr))->value_id;
      break;
    case NARY:
      gcc_assert (!PRE_EXPR_NARY (expr)->predicated_values);
      id = PRE_EXPR_NARY (expr)->value_id;
      break;
    case REFERENCE:
      id = PRE_EXPR_REFERENCE (expr)->value_id;
      break;
    default:
      gcc_unreachable ();
    }
  /* ???  We cannot assert that expr has a value-id (it can be 0), because
     we assign value-ids only to expressions that have a result
     in set_hashtable_value_ids.  */
  return id;
}

/* Return a VN valnum (SSA name or constant) for the PRE value-id VAL.  */

static tree
vn_valnum_from_value_id (unsigned int val)
{
  bitmap_iterator bi;
  unsigned int i;
  bitmap exprset = value_expressions[val];
  EXECUTE_IF_SET_IN_BITMAP (exprset, 0, i, bi)
    {
      pre_expr vexpr = expression_for_id (i);
      if (vexpr->kind == NAME)
	return VN_INFO (PRE_EXPR_NAME (vexpr))->valnum;
      else if (vexpr->kind == CONSTANT)
	return PRE_EXPR_CONSTANT (vexpr);
    }
  return NULL_TREE;
}

/* Insert an expression EXPR into a bitmapped set.  */

static void
bitmap_insert_into_set (bitmap_set_t set, pre_expr expr)
{
  unsigned int val = get_expr_value_id (expr);
  if (! value_id_constant_p (val))
    {
      /* Note this is the only function causing multiple expressions
         for the same value to appear in a set.  This is needed for
	 TMP_GEN, PHI_GEN and NEW_SETs.  */
      bitmap_set_bit (&set->values, val);
      bitmap_set_bit (&set->expressions, get_or_alloc_expression_id (expr));
    }
}

/* Copy a bitmapped set ORIG, into bitmapped set DEST.  */

static void
bitmap_set_copy (bitmap_set_t dest, bitmap_set_t orig)
{
  bitmap_copy (&dest->expressions, &orig->expressions);
  bitmap_copy (&dest->values, &orig->values);
}


/* Free memory used up by SET.  */
static void
bitmap_set_free (bitmap_set_t set)
{
  bitmap_clear (&set->expressions);
  bitmap_clear (&set->values);
}


/* Generate an topological-ordered array of bitmap set SET.  */

static vec<pre_expr> 
sorted_array_from_bitmap_set (bitmap_set_t set)
{
  unsigned int i, j;
  bitmap_iterator bi, bj;
  vec<pre_expr> result;

  /* Pre-allocate enough space for the array.  */
  result.create (bitmap_count_bits (&set->expressions));

  FOR_EACH_VALUE_ID_IN_SET (set, i, bi)
    {
      /* The number of expressions having a given value is usually
	 relatively small.  Thus, rather than making a vector of all
	 the expressions and sorting it by value-id, we walk the values
	 and check in the reverse mapping that tells us what expressions
	 have a given value, to filter those in our set.  As a result,
	 the expressions are inserted in value-id order, which means
	 topological order.

	 If this is somehow a significant lose for some cases, we can
	 choose which set to walk based on the set size.  */
      bitmap exprset = value_expressions[i];
      EXECUTE_IF_SET_IN_BITMAP (exprset, 0, j, bj)
	{
	  if (bitmap_bit_p (&set->expressions, j))
	    result.quick_push (expression_for_id (j));
        }
    }

  return result;
}

/* Subtract all expressions contained in ORIG from DEST.  */

static bitmap_set_t
bitmap_set_subtract_expressions (bitmap_set_t dest, bitmap_set_t orig)
{
  bitmap_set_t result = bitmap_set_new ();
  bitmap_iterator bi;
  unsigned int i;

  bitmap_and_compl (&result->expressions, &dest->expressions,
		    &orig->expressions);

  FOR_EACH_EXPR_ID_IN_SET (result, i, bi)
    {
      pre_expr expr = expression_for_id (i);
      unsigned int value_id = get_expr_value_id (expr);
      bitmap_set_bit (&result->values, value_id);
    }

  return result;
}

/* Subtract all values in bitmap set B from bitmap set A.  */

static void
bitmap_set_subtract_values (bitmap_set_t a, bitmap_set_t b)
{
  unsigned int i;
  bitmap_iterator bi;
  unsigned to_remove = -1U;
  bitmap_and_compl_into (&a->values, &b->values);
  FOR_EACH_EXPR_ID_IN_SET (a, i, bi)
    {
      if (to_remove != -1U)
	{
	  bitmap_clear_bit (&a->expressions, to_remove);
	  to_remove = -1U;
	}
      pre_expr expr = expression_for_id (i);
      if (! bitmap_bit_p (&a->values, get_expr_value_id (expr)))
	to_remove = i;
    }
  if (to_remove != -1U)
    bitmap_clear_bit (&a->expressions, to_remove);
}


/* Return true if bitmapped set SET contains the value VALUE_ID.  */

static bool
bitmap_set_contains_value (bitmap_set_t set, unsigned int value_id)
{
  if (value_id_constant_p (value_id))
    return true;

  return bitmap_bit_p (&set->values, value_id);
}

/* Return true if two bitmap sets are equal.  */

static bool
bitmap_set_equal (bitmap_set_t a, bitmap_set_t b)
{
  return bitmap_equal_p (&a->values, &b->values);
}

/* Replace an instance of EXPR's VALUE with EXPR in SET if it exists,
   and add it otherwise.  */

static void
bitmap_value_replace_in_set (bitmap_set_t set, pre_expr expr)
{
  unsigned int val = get_expr_value_id (expr);
  if (value_id_constant_p (val))
    return;

  if (bitmap_set_contains_value (set, val))
    {
      /* The number of expressions having a given value is usually
	 significantly less than the total number of expressions in SET.
	 Thus, rather than check, for each expression in SET, whether it
	 has the value LOOKFOR, we walk the reverse mapping that tells us
	 what expressions have a given value, and see if any of those
	 expressions are in our set.  For large testcases, this is about
	 5-10x faster than walking the bitmap.  If this is somehow a
	 significant lose for some cases, we can choose which set to walk
	 based on the set size.  */
      unsigned int i;
      bitmap_iterator bi;
      bitmap exprset = value_expressions[val];
      EXECUTE_IF_SET_IN_BITMAP (exprset, 0, i, bi)
	{
	  if (bitmap_clear_bit (&set->expressions, i))
	    {
	      bitmap_set_bit (&set->expressions, get_expression_id (expr));
	      return;
	    }
	}
      gcc_unreachable ();
    }
  else
    bitmap_insert_into_set (set, expr);
}

/* Insert EXPR into SET if EXPR's value is not already present in
   SET.  */

static void
bitmap_value_insert_into_set (bitmap_set_t set, pre_expr expr)
{
  unsigned int val = get_expr_value_id (expr);

  gcc_checking_assert (expr->id == get_or_alloc_expression_id (expr));

  /* Constant values are always considered to be part of the set.  */
  if (value_id_constant_p (val))
    return;

  /* If the value membership changed, add the expression.  */
  if (bitmap_set_bit (&set->values, val))
    bitmap_set_bit (&set->expressions, expr->id);
}

/* Print out EXPR to outfile.  */

static void
print_pre_expr (FILE *outfile, const pre_expr expr)
{
  if (! expr)
    {
      fprintf (outfile, "NULL");
      return;
    }
  switch (expr->kind)
    {
    case CONSTANT:
      print_generic_expr (outfile, PRE_EXPR_CONSTANT (expr));
      break;
    case NAME:
      print_generic_expr (outfile, PRE_EXPR_NAME (expr));
      break;
    case NARY:
      {
	unsigned int i;
	vn_nary_op_t nary = PRE_EXPR_NARY (expr);
	fprintf (outfile, "{%s,", get_tree_code_name (nary->opcode));
	for (i = 0; i < nary->length; i++)
	  {
	    print_generic_expr (outfile, nary->op[i]);
	    if (i != (unsigned) nary->length - 1)
	      fprintf (outfile, ",");
	  }
	fprintf (outfile, "}");
      }
      break;

    case REFERENCE:
      {
	vn_reference_op_t vro;
	unsigned int i;
	vn_reference_t ref = PRE_EXPR_REFERENCE (expr);
	fprintf (outfile, "{");
	for (i = 0;
	     ref->operands.iterate (i, &vro);
	     i++)
	  {
	    bool closebrace = false;
	    if (vro->opcode != SSA_NAME
		&& TREE_CODE_CLASS (vro->opcode) != tcc_declaration)
	      {
		fprintf (outfile, "%s", get_tree_code_name (vro->opcode));
		if (vro->op0)
		  {
		    fprintf (outfile, "<");
		    closebrace = true;
		  }
	      }
	    if (vro->op0)
	      {
		print_generic_expr (outfile, vro->op0);
		if (vro->op1)
		  {
		    fprintf (outfile, ",");
		    print_generic_expr (outfile, vro->op1);
		  }
		if (vro->op2)
		  {
		    fprintf (outfile, ",");
		    print_generic_expr (outfile, vro->op2);
		  }
	      }
	    if (closebrace)
		fprintf (outfile, ">");
	    if (i != ref->operands.length () - 1)
	      fprintf (outfile, ",");
	  }
	fprintf (outfile, "}");
	if (ref->vuse)
	  {
	    fprintf (outfile, "@");
	    print_generic_expr (outfile, ref->vuse);
	  }
      }
      break;
    }
}
void debug_pre_expr (pre_expr);

/* Like print_pre_expr but always prints to stderr.  */
DEBUG_FUNCTION void
debug_pre_expr (pre_expr e)
{
  print_pre_expr (stderr, e);
  fprintf (stderr, "\n");
}

/* Print out SET to OUTFILE.  */

static void
print_bitmap_set (FILE *outfile, bitmap_set_t set,
		  const char *setname, int blockindex)
{
  fprintf (outfile, "%s[%d] := { ", setname, blockindex);
  if (set)
    {
      bool first = true;
      unsigned i;
      bitmap_iterator bi;

      FOR_EACH_EXPR_ID_IN_SET (set, i, bi)
	{
	  const pre_expr expr = expression_for_id (i);

	  if (!first)
	    fprintf (outfile, ", ");
	  first = false;
	  print_pre_expr (outfile, expr);

	  fprintf (outfile, " (%04d)", get_expr_value_id (expr));
	}
    }
  fprintf (outfile, " }\n");
}

void debug_bitmap_set (bitmap_set_t);

DEBUG_FUNCTION void
debug_bitmap_set (bitmap_set_t set)
{
  print_bitmap_set (stderr, set, "debug", 0);
}

void debug_bitmap_sets_for (basic_block);

DEBUG_FUNCTION void
debug_bitmap_sets_for (basic_block bb)
{
  print_bitmap_set (stderr, AVAIL_OUT (bb), "avail_out", bb->index);
  print_bitmap_set (stderr, EXP_GEN (bb), "exp_gen", bb->index);
  print_bitmap_set (stderr, PHI_GEN (bb), "phi_gen", bb->index);
  print_bitmap_set (stderr, TMP_GEN (bb), "tmp_gen", bb->index);
  print_bitmap_set (stderr, ANTIC_IN (bb), "antic_in", bb->index);
  if (do_partial_partial)
    print_bitmap_set (stderr, PA_IN (bb), "pa_in", bb->index);
  print_bitmap_set (stderr, NEW_SETS (bb), "new_sets", bb->index);
}

/* Print out the expressions that have VAL to OUTFILE.  */

static void
print_value_expressions (FILE *outfile, unsigned int val)
{
  bitmap set = value_expressions[val];
  if (set)
    {
      bitmap_set x;
      char s[10];
      sprintf (s, "%04d", val);
      x.expressions = *set;
      print_bitmap_set (outfile, &x, s, 0);
    }
}


DEBUG_FUNCTION void
debug_value_expressions (unsigned int val)
{
  print_value_expressions (stderr, val);
}

/* Given a CONSTANT, allocate a new CONSTANT type PRE_EXPR to
   represent it.  */

static pre_expr
get_or_alloc_expr_for_constant (tree constant)
{
  unsigned int result_id;
  unsigned int value_id;
  struct pre_expr_d expr;
  pre_expr newexpr;

  expr.kind = CONSTANT;
  PRE_EXPR_CONSTANT (&expr) = constant;
  result_id = lookup_expression_id (&expr);
  if (result_id != 0)
    return expression_for_id (result_id);

  newexpr = pre_expr_pool.allocate ();
  newexpr->kind = CONSTANT;
  PRE_EXPR_CONSTANT (newexpr) = constant;
  alloc_expression_id (newexpr);
  value_id = get_or_alloc_constant_value_id (constant);
  add_to_value (value_id, newexpr);
  return newexpr;
}

/* Get or allocate a pre_expr for a piece of GIMPLE, and return it.
   Currently only supports constants and SSA_NAMES.  */
static pre_expr
get_or_alloc_expr_for (tree t)
{
  if (TREE_CODE (t) == SSA_NAME)
    return get_or_alloc_expr_for_name (t);
  else if (is_gimple_min_invariant (t))
    return get_or_alloc_expr_for_constant (t);
  gcc_unreachable ();
}

/* Return the folded version of T if T, when folded, is a gimple
   min_invariant or an SSA name.  Otherwise, return T.  */

static pre_expr
fully_constant_expression (pre_expr e)
{
  switch (e->kind)
    {
    case CONSTANT:
      return e;
    case NARY:
      {
	vn_nary_op_t nary = PRE_EXPR_NARY (e);
	tree res = vn_nary_simplify (nary);
	if (!res)
	  return e;
	if (is_gimple_min_invariant (res))
	  return get_or_alloc_expr_for_constant (res);
	if (TREE_CODE (res) == SSA_NAME)
	  return get_or_alloc_expr_for_name (res);
	return e;
      }
    case REFERENCE:
      {
	vn_reference_t ref = PRE_EXPR_REFERENCE (e);
	tree folded;
	if ((folded = fully_constant_vn_reference_p (ref)))
	  return get_or_alloc_expr_for_constant (folded);
	return e;
      }
    default:
      return e;
    }
  return e;
}

/* Translate the VUSE backwards through phi nodes in PHIBLOCK, so that
   it has the value it would have in BLOCK.  Set *SAME_VALID to true
   in case the new vuse doesn't change the value id of the OPERANDS.  */

static tree
translate_vuse_through_block (vec<vn_reference_op_s> operands,
			      alias_set_type set, tree type, tree vuse,
			      basic_block phiblock,
			      basic_block block, bool *same_valid)
{
  gimple *phi = SSA_NAME_DEF_STMT (vuse);
  ao_ref ref;
  edge e = NULL;
  bool use_oracle;

  if (same_valid)
    *same_valid = true;

  if (gimple_bb (phi) != phiblock)
    return vuse;

  unsigned int cnt = PARAM_VALUE (PARAM_SCCVN_MAX_ALIAS_QUERIES_PER_ACCESS);
  use_oracle = ao_ref_init_from_vn_reference (&ref, set, type, operands);

  /* Use the alias-oracle to find either the PHI node in this block,
     the first VUSE used in this block that is equivalent to vuse or
     the first VUSE which definition in this block kills the value.  */
  if (gimple_code (phi) == GIMPLE_PHI)
    e = find_edge (block, phiblock);
  else if (use_oracle)
    while (cnt > 0
	   && !stmt_may_clobber_ref_p_1 (phi, &ref))
      {
	--cnt;
	vuse = gimple_vuse (phi);
	phi = SSA_NAME_DEF_STMT (vuse);
	if (gimple_bb (phi) != phiblock)
	  return vuse;
	if (gimple_code (phi) == GIMPLE_PHI)
	  {
	    e = find_edge (block, phiblock);
	    break;
	  }
      }
  else
    return NULL_TREE;

  if (e)
    {
      if (use_oracle && same_valid)
	{
	  bitmap visited = NULL;
	  /* Try to find a vuse that dominates this phi node by skipping
	     non-clobbering statements.  */
	  vuse = get_continuation_for_phi (phi, &ref, cnt, &visited, false,
					   NULL, NULL);
	  if (visited)
	    BITMAP_FREE (visited);
	}
      else
	vuse = NULL_TREE;
      /* If we didn't find any, the value ID can't stay the same.  */
      if (!vuse && same_valid)
	*same_valid = false;
      /* ??? We would like to return vuse here as this is the canonical
         upmost vdef that this reference is associated with.  But during
	 insertion of the references into the hash tables we only ever
	 directly insert with their direct gimple_vuse, hence returning
	 something else would make us not find the other expression.  */
      return PHI_ARG_DEF (phi, e->dest_idx);
    }

  return NULL_TREE;
}

/* Like bitmap_find_leader, but checks for the value existing in SET1 *or*
   SET2 *or* SET3.  This is used to avoid making a set consisting of the union
   of PA_IN and ANTIC_IN during insert and phi-translation.  */

static inline pre_expr
find_leader_in_sets (unsigned int val, bitmap_set_t set1, bitmap_set_t set2,
		     bitmap_set_t set3 = NULL)
{
  pre_expr result = NULL;

  if (set1)
    result = bitmap_find_leader (set1, val);
  if (!result && set2)
    result = bitmap_find_leader (set2, val);
  if (!result && set3)
    result = bitmap_find_leader (set3, val);
  return result;
}

/* Get the tree type for our PRE expression e.  */

static tree
get_expr_type (const pre_expr e)
{
  switch (e->kind)
    {
    case NAME:
      return TREE_TYPE (PRE_EXPR_NAME (e));
    case CONSTANT:
      return TREE_TYPE (PRE_EXPR_CONSTANT (e));
    case REFERENCE:
      return PRE_EXPR_REFERENCE (e)->type;
    case NARY:
      return PRE_EXPR_NARY (e)->type;
    }
  gcc_unreachable ();
}

/* Get a representative SSA_NAME for a given expression that is available in B.
   Since all of our sub-expressions are treated as values, we require
   them to be SSA_NAME's for simplicity.
   Prior versions of GVNPRE used to use "value handles" here, so that
   an expression would be VH.11 + VH.10 instead of d_3 + e_6.  In
   either case, the operands are really values (IE we do not expect
   them to be usable without finding leaders).  */

static tree
get_representative_for (const pre_expr e, basic_block b = NULL)
{
  tree name, valnum = NULL_TREE;
  unsigned int value_id = get_expr_value_id (e);

  switch (e->kind)
    {
    case NAME:
      return PRE_EXPR_NAME (e);
    case CONSTANT:
      return PRE_EXPR_CONSTANT (e);
    case NARY:
    case REFERENCE:
      {
	/* Go through all of the expressions representing this value
	   and pick out an SSA_NAME.  */
	unsigned int i;
	bitmap_iterator bi;
	bitmap exprs = value_expressions[value_id];
	EXECUTE_IF_SET_IN_BITMAP (exprs, 0, i, bi)
	  {
	    pre_expr rep = expression_for_id (i);
	    if (rep->kind == NAME)
	      {
		tree name = PRE_EXPR_NAME (rep);
		valnum = VN_INFO (name)->valnum;
		gimple *def = SSA_NAME_DEF_STMT (name);
		/* We have to return either a new representative or one
		   that can be used for expression simplification and thus
		   is available in B.  */
		if (! b 
		    || gimple_nop_p (def)
		    || dominated_by_p (CDI_DOMINATORS, b, gimple_bb (def)))
		  return name;
	      }
	    else if (rep->kind == CONSTANT)
	      return PRE_EXPR_CONSTANT (rep);
	  }
      }
      break;
    }

  /* If we reached here we couldn't find an SSA_NAME.  This can
     happen when we've discovered a value that has never appeared in
     the program as set to an SSA_NAME, as the result of phi translation.
     Create one here.
     ???  We should be able to re-use this when we insert the statement
     to compute it.  */
  name = make_temp_ssa_name (get_expr_type (e), gimple_build_nop (), "pretmp");
  VN_INFO (name)->value_id = value_id;
  VN_INFO (name)->valnum = valnum ? valnum : name;
  /* ???  For now mark this SSA name for release by VN.  */
  VN_INFO (name)->needs_insertion = true;
  add_to_value (value_id, get_or_alloc_expr_for_name (name));
  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Created SSA_NAME representative ");
      print_generic_expr (dump_file, name);
      fprintf (dump_file, " for expression:");
      print_pre_expr (dump_file, e);
      fprintf (dump_file, " (%04d)\n", value_id);
    }

  return name;
}


static pre_expr
phi_translate (bitmap_set_t, pre_expr, bitmap_set_t, bitmap_set_t, edge);

/* Translate EXPR using phis in PHIBLOCK, so that it has the values of
   the phis in PRED.  Return NULL if we can't find a leader for each part
   of the translated expression.  */

static pre_expr
phi_translate_1 (bitmap_set_t dest,
		 pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, edge e)
{
  basic_block pred = e->src;
  basic_block phiblock = e->dest;
  switch (expr->kind)
    {
    case NARY:
      {
	unsigned int i;
	bool changed = false;
	vn_nary_op_t nary = PRE_EXPR_NARY (expr);
	vn_nary_op_t newnary = XALLOCAVAR (struct vn_nary_op_s,
					   sizeof_vn_nary_op (nary->length));
	memcpy (newnary, nary, sizeof_vn_nary_op (nary->length));

	for (i = 0; i < newnary->length; i++)
	  {
	    if (TREE_CODE (newnary->op[i]) != SSA_NAME)
	      continue;
	    else
	      {
                pre_expr leader, result;
		unsigned int op_val_id = VN_INFO (newnary->op[i])->value_id;
		leader = find_leader_in_sets (op_val_id, set1, set2);
		result = phi_translate (dest, leader, set1, set2, e);
		if (result && result != leader)
		  /* If op has a leader in the sets we translate make
		     sure to use the value of the translated expression.
		     We might need a new representative for that.  */
		  newnary->op[i] = get_representative_for (result, pred);
		else if (!result)
		  return NULL;

		changed |= newnary->op[i] != nary->op[i];
	      }
	  }
	if (changed)
	  {
	    pre_expr constant;
	    unsigned int new_val_id;

	    PRE_EXPR_NARY (expr) = newnary;
	    constant = fully_constant_expression (expr);
	    PRE_EXPR_NARY (expr) = nary;
	    if (constant != expr)
	      {
		/* For non-CONSTANTs we have to make sure we can eventually
		   insert the expression.  Which means we need to have a
		   leader for it.  */
		if (constant->kind != CONSTANT)
		  {
		    /* Do not allow simplifications to non-constants over
		       backedges as this will likely result in a loop PHI node
		       to be inserted and increased register pressure.
		       See PR77498 - this avoids doing predcoms work in
		       a less efficient way.  */
		    if (e->flags & EDGE_DFS_BACK)
		      ;
		    else
		      {
			unsigned value_id = get_expr_value_id (constant);
			/* We want a leader in ANTIC_OUT or AVAIL_OUT here.
			   dest has what we computed into ANTIC_OUT sofar
			   so pick from that - since topological sorting
			   by sorted_array_from_bitmap_set isn't perfect
			   we may lose some cases here.  */
			constant = find_leader_in_sets (value_id, dest,
							AVAIL_OUT (pred));
			if (constant)
			  {
			    if (dump_file && (dump_flags & TDF_DETAILS))
			      {
				fprintf (dump_file, "simplifying ");
				print_pre_expr (dump_file, expr);
				fprintf (dump_file, " translated %d -> %d to ",
					 phiblock->index, pred->index);
				PRE_EXPR_NARY (expr) = newnary;
				print_pre_expr (dump_file, expr);
				PRE_EXPR_NARY (expr) = nary;
				fprintf (dump_file, " to ");
				print_pre_expr (dump_file, constant);
				fprintf (dump_file, "\n");
			      }
			    return constant;
			  }
		      }
		  }
		else
		  return constant;
	      }

	    /* vn_nary_* do not valueize operands.  */
	    for (i = 0; i < newnary->length; ++i)
	      if (TREE_CODE (newnary->op[i]) == SSA_NAME)
		newnary->op[i] = VN_INFO (newnary->op[i])->valnum;
	    tree result = vn_nary_op_lookup_pieces (newnary->length,
						    newnary->opcode,
						    newnary->type,
						    &newnary->op[0],
						    &nary);
	    if (result && is_gimple_min_invariant (result))
	      return get_or_alloc_expr_for_constant (result);

	    expr = pre_expr_pool.allocate ();
	    expr->kind = NARY;
	    expr->id = 0;
	    if (nary && !nary->predicated_values)
	      {
		PRE_EXPR_NARY (expr) = nary;
		new_val_id = nary->value_id;
		get_or_alloc_expression_id (expr);
	      }
	    else
	      {
		new_val_id = get_next_value_id ();
		value_expressions.safe_grow_cleared (get_max_value_id () + 1);
		nary = vn_nary_op_insert_pieces (newnary->length,
						 newnary->opcode,
						 newnary->type,
						 &newnary->op[0],
						 result, new_val_id);
		PRE_EXPR_NARY (expr) = nary;
		get_or_alloc_expression_id (expr);
	      }
	    add_to_value (new_val_id, expr);
	  }
	return expr;
      }
      break;

    case REFERENCE:
      {
	vn_reference_t ref = PRE_EXPR_REFERENCE (expr);
	vec<vn_reference_op_s> operands = ref->operands;
	tree vuse = ref->vuse;
	tree newvuse = vuse;
	vec<vn_reference_op_s> newoperands = vNULL;
	bool changed = false, same_valid = true;
	unsigned int i, n;
	vn_reference_op_t operand;
	vn_reference_t newref;

	for (i = 0; operands.iterate (i, &operand); i++)
	  {
	    pre_expr opresult;
	    pre_expr leader;
	    tree op[3];
	    tree type = operand->type;
	    vn_reference_op_s newop = *operand;
	    op[0] = operand->op0;
	    op[1] = operand->op1;
	    op[2] = operand->op2;
	    for (n = 0; n < 3; ++n)
	      {
		unsigned int op_val_id;
		if (!op[n])
		  continue;
		if (TREE_CODE (op[n]) != SSA_NAME)
		  {
		    /* We can't possibly insert these.  */
		    if (n != 0
			&& !is_gimple_min_invariant (op[n]))
		      break;
		    continue;
		  }
		op_val_id = VN_INFO (op[n])->value_id;
		leader = find_leader_in_sets (op_val_id, set1, set2);
		opresult = phi_translate (dest, leader, set1, set2, e);
		if (opresult && opresult != leader)
		  {
		    tree name = get_representative_for (opresult);
		    changed |= name != op[n];
		    op[n] = name;
		  }
		else if (!opresult)
		  break;
	      }
	    if (n != 3)
	      {
		newoperands.release ();
		return NULL;
	      }
	    if (!changed)
	      continue;
	    if (!newoperands.exists ())
	      newoperands = operands.copy ();
	    /* We may have changed from an SSA_NAME to a constant */
	    if (newop.opcode == SSA_NAME && TREE_CODE (op[0]) != SSA_NAME)
	      newop.opcode = TREE_CODE (op[0]);
	    newop.type = type;
	    newop.op0 = op[0];
	    newop.op1 = op[1];
	    newop.op2 = op[2];
	    newoperands[i] = newop;
	  }
	gcc_checking_assert (i == operands.length ());

	if (vuse)
	  {
	    newvuse = translate_vuse_through_block (newoperands.exists ()
						    ? newoperands : operands,
						    ref->set, ref->type,
						    vuse, phiblock, pred,
						    changed
						    ? NULL : &same_valid);
	    if (newvuse == NULL_TREE)
	      {
		newoperands.release ();
		return NULL;
	      }
	  }

	if (changed || newvuse != vuse)
	  {
	    unsigned int new_val_id;

	    tree result = vn_reference_lookup_pieces (newvuse, ref->set,
						      ref->type,
						      newoperands.exists ()
						      ? newoperands : operands,
						      &newref, VN_WALK);
	    if (result)
	      newoperands.release ();

	    /* We can always insert constants, so if we have a partial
	       redundant constant load of another type try to translate it
	       to a constant of appropriate type.  */
	    if (result && is_gimple_min_invariant (result))
	      {
		tree tem = result;
		if (!useless_type_conversion_p (ref->type, TREE_TYPE (result)))
		  {
		    tem = fold_unary (VIEW_CONVERT_EXPR, ref->type, result);
		    if (tem && !is_gimple_min_invariant (tem))
		      tem = NULL_TREE;
		  }
		if (tem)
		  return get_or_alloc_expr_for_constant (tem);
	      }

	    /* If we'd have to convert things we would need to validate
	       if we can insert the translated expression.  So fail
	       here for now - we cannot insert an alias with a different
	       type in the VN tables either, as that would assert.  */
	    if (result
		&& !useless_type_conversion_p (ref->type, TREE_TYPE (result)))
	      return NULL;
	    else if (!result && newref
		     && !useless_type_conversion_p (ref->type, newref->type))
	      {
		newoperands.release ();
		return NULL;
	      }

	    expr = pre_expr_pool.allocate ();
	    expr->kind = REFERENCE;
	    expr->id = 0;

	    if (newref)
	      new_val_id = newref->value_id;
	    else
	      {
		if (changed || !same_valid)
		  {
		    new_val_id = get_next_value_id ();
		    value_expressions.safe_grow_cleared
		      (get_max_value_id () + 1);
		  }
		else
		  new_val_id = ref->value_id;
		if (!newoperands.exists ())
		  newoperands = operands.copy ();
		newref = vn_reference_insert_pieces (newvuse, ref->set,
						     ref->type,
						     newoperands,
						     result, new_val_id);
		newoperands = vNULL;
	      }
	    PRE_EXPR_REFERENCE (expr) = newref;
	    get_or_alloc_expression_id (expr);
	    add_to_value (new_val_id, expr);
	  }
	newoperands.release ();
	return expr;
      }
      break;

    case NAME:
      {
	tree name = PRE_EXPR_NAME (expr);
	gimple *def_stmt = SSA_NAME_DEF_STMT (name);
	/* If the SSA name is defined by a PHI node in this block,
	   translate it.  */
	if (gimple_code (def_stmt) == GIMPLE_PHI
	    && gimple_bb (def_stmt) == phiblock)
	  {
	    tree def = PHI_ARG_DEF (def_stmt, e->dest_idx);

	    /* Handle constant. */
	    if (is_gimple_min_invariant (def))
	      return get_or_alloc_expr_for_constant (def);

	    return get_or_alloc_expr_for_name (def);
	  }
	/* Otherwise return it unchanged - it will get removed if its
	   value is not available in PREDs AVAIL_OUT set of expressions
	   by the subtraction of TMP_GEN.  */
	return expr;
      }

    default:
      gcc_unreachable ();
    }
}

/* Wrapper around phi_translate_1 providing caching functionality.  */

static pre_expr
phi_translate (bitmap_set_t dest, pre_expr expr,
	       bitmap_set_t set1, bitmap_set_t set2, edge e)
{
  expr_pred_trans_t slot = NULL;
  pre_expr phitrans;

  if (!expr)
    return NULL;

  /* Constants contain no values that need translation.  */
  if (expr->kind == CONSTANT)
    return expr;

  if (value_id_constant_p (get_expr_value_id (expr)))
    return expr;

  /* Don't add translations of NAMEs as those are cheap to translate.  */
  if (expr->kind != NAME)
    {
      if (phi_trans_add (&slot, expr, e->src))
	return slot->v;
      /* Store NULL for the value we want to return in the case of
	 recursing.  */
      slot->v = NULL;
    }

  /* Translate.  */
  basic_block saved_valueize_bb = vn_context_bb;
  vn_context_bb = e->src;
  phitrans = phi_translate_1 (dest, expr, set1, set2, e);
  vn_context_bb = saved_valueize_bb;

  if (slot)
    {
      if (phitrans)
	slot->v = phitrans;
      else
	/* Remove failed translations again, they cause insert
	   iteration to not pick up new opportunities reliably.  */
	phi_translate_table->remove_elt_with_hash (slot, slot->hashcode);
    }

  return phitrans;
}


/* For each expression in SET, translate the values through phi nodes
   in PHIBLOCK using edge PHIBLOCK->PRED, and store the resulting
   expressions in DEST.  */

static void
phi_translate_set (bitmap_set_t dest, bitmap_set_t set, edge e)
{
  vec<pre_expr> exprs;
  pre_expr expr;
  int i;

  if (gimple_seq_empty_p (phi_nodes (e->dest)))
    {
      bitmap_set_copy (dest, set);
      return;
    }

  exprs = sorted_array_from_bitmap_set (set);
  FOR_EACH_VEC_ELT (exprs, i, expr)
    {
      pre_expr translated;
      translated = phi_translate (dest, expr, set, NULL, e);
      if (!translated)
	continue;

      bitmap_insert_into_set (dest, translated);
    }
  exprs.release ();
}

/* Find the leader for a value (i.e., the name representing that
   value) in a given set, and return it.  Return NULL if no leader
   is found.  */

static pre_expr
bitmap_find_leader (bitmap_set_t set, unsigned int val)
{
  if (value_id_constant_p (val))
    {
      unsigned int i;
      bitmap_iterator bi;
      bitmap exprset = value_expressions[val];

      EXECUTE_IF_SET_IN_BITMAP (exprset, 0, i, bi)
	{
	  pre_expr expr = expression_for_id (i);
	  if (expr->kind == CONSTANT)
	    return expr;
	}
    }
  if (bitmap_set_contains_value (set, val))
    {
      /* Rather than walk the entire bitmap of expressions, and see
	 whether any of them has the value we are looking for, we look
	 at the reverse mapping, which tells us the set of expressions
	 that have a given value (IE value->expressions with that
	 value) and see if any of those expressions are in our set.
	 The number of expressions per value is usually significantly
	 less than the number of expressions in the set.  In fact, for
	 large testcases, doing it this way is roughly 5-10x faster
	 than walking the bitmap.
	 If this is somehow a significant lose for some cases, we can
	 choose which set to walk based on which set is smaller.  */
      unsigned int i;
      bitmap_iterator bi;
      bitmap exprset = value_expressions[val];

      EXECUTE_IF_AND_IN_BITMAP (exprset, &set->expressions, 0, i, bi)
	return expression_for_id (i);
    }
  return NULL;
}

/* Determine if EXPR, a memory expression, is ANTIC_IN at the top of
   BLOCK by seeing if it is not killed in the block.  Note that we are
   only determining whether there is a store that kills it.  Because
   of the order in which clean iterates over values, we are guaranteed
   that altered operands will have caused us to be eliminated from the
   ANTIC_IN set already.  */

static bool
value_dies_in_block_x (pre_expr expr, basic_block block)
{
  tree vuse = PRE_EXPR_REFERENCE (expr)->vuse;
  vn_reference_t refx = PRE_EXPR_REFERENCE (expr);
  gimple *def;
  gimple_stmt_iterator gsi;
  unsigned id = get_expression_id (expr);
  bool res = false;
  ao_ref ref;

  if (!vuse)
    return false;

  /* Lookup a previously calculated result.  */
  if (EXPR_DIES (block)
      && bitmap_bit_p (EXPR_DIES (block), id * 2))
    return bitmap_bit_p (EXPR_DIES (block), id * 2 + 1);

  /* A memory expression {e, VUSE} dies in the block if there is a
     statement that may clobber e.  If, starting statement walk from the
     top of the basic block, a statement uses VUSE there can be no kill
     inbetween that use and the original statement that loaded {e, VUSE},
     so we can stop walking.  */
  ref.base = NULL_TREE;
  for (gsi = gsi_start_bb (block); !gsi_end_p (gsi); gsi_next (&gsi))
    {
      tree def_vuse, def_vdef;
      def = gsi_stmt (gsi);
      def_vuse = gimple_vuse (def);
      def_vdef = gimple_vdef (def);

      /* Not a memory statement.  */
      if (!def_vuse)
	continue;

      /* Not a may-def.  */
      if (!def_vdef)
	{
	  /* A load with the same VUSE, we're done.  */
	  if (def_vuse == vuse)
	    break;

	  continue;
	}

      /* Init ref only if we really need it.  */
      if (ref.base == NULL_TREE
	  && !ao_ref_init_from_vn_reference (&ref, refx->set, refx->type,
					     refx->operands))
	{
	  res = true;
	  break;
	}
      /* If the statement may clobber expr, it dies.  */
      if (stmt_may_clobber_ref_p_1 (def, &ref))
	{
	  res = true;
	  break;
	}
    }

  /* Remember the result.  */
  if (!EXPR_DIES (block))
    EXPR_DIES (block) = BITMAP_ALLOC (&grand_bitmap_obstack);
  bitmap_set_bit (EXPR_DIES (block), id * 2);
  if (res)
    bitmap_set_bit (EXPR_DIES (block), id * 2 + 1);

  return res;
}


/* Determine if OP is valid in SET1 U SET2, which it is when the union
   contains its value-id.  */

static bool
op_valid_in_sets (bitmap_set_t set1, bitmap_set_t set2, tree op)
{
  if (op && TREE_CODE (op) == SSA_NAME)
    {
      unsigned int value_id = VN_INFO (op)->value_id;
      if (!(bitmap_set_contains_value (set1, value_id)
	    || (set2 && bitmap_set_contains_value  (set2, value_id))))
	return false;
    }
  return true;
}

/* Determine if the expression EXPR is valid in SET1 U SET2.
   ONLY SET2 CAN BE NULL.
   This means that we have a leader for each part of the expression
   (if it consists of values), or the expression is an SSA_NAME.
   For loads/calls, we also see if the vuse is killed in this block.  */

static bool
valid_in_sets (bitmap_set_t set1, bitmap_set_t set2, pre_expr expr)
{
  switch (expr->kind)
    {
    case NAME:
      /* By construction all NAMEs are available.  Non-available
	 NAMEs are removed by subtracting TMP_GEN from the sets.  */
      return true;
    case NARY:
      {
	unsigned int i;
	vn_nary_op_t nary = PRE_EXPR_NARY (expr);
	for (i = 0; i < nary->length; i++)
	  if (!op_valid_in_sets (set1, set2, nary->op[i]))
	    return false;
	return true;
      }
      break;
    case REFERENCE:
      {
	vn_reference_t ref = PRE_EXPR_REFERENCE (expr);
	vn_reference_op_t vro;
	unsigned int i;

	FOR_EACH_VEC_ELT (ref->operands, i, vro)
	  {
	    if (!op_valid_in_sets (set1, set2, vro->op0)
		|| !op_valid_in_sets (set1, set2, vro->op1)
		|| !op_valid_in_sets (set1, set2, vro->op2))
	      return false;
	  }
	return true;
      }
    default:
      gcc_unreachable ();
    }
}

/* Clean the set of expressions SET1 that are no longer valid in SET1 or SET2.
   This means expressions that are made up of values we have no leaders for
   in SET1 or SET2.  */

static void
clean (bitmap_set_t set1, bitmap_set_t set2 = NULL)
{
  vec<pre_expr> exprs = sorted_array_from_bitmap_set (set1);
  pre_expr expr;
  int i;

  FOR_EACH_VEC_ELT (exprs, i, expr)
    {
      if (!valid_in_sets (set1, set2, expr))
	{
	  unsigned int val  = get_expr_value_id (expr);
	  bitmap_clear_bit (&set1->expressions, get_expression_id (expr));
	  /* We are entered with possibly multiple expressions for a value
	     so before removing a value from the set see if there's an
	     expression for it left.  */
	  if (! bitmap_find_leader (set1, val))
	    bitmap_clear_bit (&set1->values, val);
	}
    }
  exprs.release ();
}

/* Clean the set of expressions that are no longer valid in SET because
   they are clobbered in BLOCK or because they trap and may not be executed.  */

static void
prune_clobbered_mems (bitmap_set_t set, basic_block block)
{
  bitmap_iterator bi;
  unsigned i;
  unsigned to_remove = -1U;
  bool any_removed = false;

  FOR_EACH_EXPR_ID_IN_SET (set, i, bi)
    {
      /* Remove queued expr.  */
      if (to_remove != -1U)
	{
	  bitmap_clear_bit (&set->expressions, to_remove);
	  any_removed = true;
	  to_remove = -1U;
	}

      pre_expr expr = expression_for_id (i);
      if (expr->kind == REFERENCE)
	{
	  vn_reference_t ref = PRE_EXPR_REFERENCE (expr);
	  if (ref->vuse)
	    {
	      gimple *def_stmt = SSA_NAME_DEF_STMT (ref->vuse);
	      if (!gimple_nop_p (def_stmt)
		  && ((gimple_bb (def_stmt) != block
		       && !dominated_by_p (CDI_DOMINATORS,
					   block, gimple_bb (def_stmt)))
		      || (gimple_bb (def_stmt) == block
			  && value_dies_in_block_x (expr, block))))
		to_remove = i;
	    }
	}
      else if (expr->kind == NARY)
	{
	  vn_nary_op_t nary = PRE_EXPR_NARY (expr);
	  /* If the NARY may trap make sure the block does not contain
	     a possible exit point.
	     ???  This is overly conservative if we translate AVAIL_OUT
	     as the available expression might be after the exit point.  */
	  if (BB_MAY_NOTRETURN (block)
	      && vn_nary_may_trap (nary))
	    to_remove = i;
	}
    }

  /* Remove queued expr.  */
  if (to_remove != -1U)
    {
      bitmap_clear_bit (&set->expressions, to_remove);
      any_removed = true;
    }

  /* Above we only removed expressions, now clean the set of values
     which no longer have any corresponding expression.  We cannot
     clear the value at the time we remove an expression since there
     may be multiple expressions per value.
     If we'd queue possibly to be removed values we could use
     the bitmap_find_leader way to see if there's still an expression
     for it.  For some ratio of to be removed values and number of
     values/expressions in the set this might be faster than rebuilding
     the value-set.  */
  if (any_removed)
    {
      bitmap_clear (&set->values);
      FOR_EACH_EXPR_ID_IN_SET (set, i, bi)
	{
	  pre_expr expr = expression_for_id (i);
	  unsigned int value_id = get_expr_value_id (expr);
	  bitmap_set_bit (&set->values, value_id);
	}
    }
}

static sbitmap has_abnormal_preds;

/* Compute the ANTIC set for BLOCK.

   If succs(BLOCK) > 1 then
     ANTIC_OUT[BLOCK] = intersection of ANTIC_IN[b] for all succ(BLOCK)
   else if succs(BLOCK) == 1 then
     ANTIC_OUT[BLOCK] = phi_translate (ANTIC_IN[succ(BLOCK)])

   ANTIC_IN[BLOCK] = clean(ANTIC_OUT[BLOCK] U EXP_GEN[BLOCK] - TMP_GEN[BLOCK])

   Note that clean() is deferred until after the iteration.  */

static bool
compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge)
{
  bitmap_set_t S, old, ANTIC_OUT;
  edge e;
  edge_iterator ei;

  bool was_visited = BB_VISITED (block);
  bool changed = ! BB_VISITED (block);
  BB_VISITED (block) = 1;
  old = ANTIC_OUT = S = NULL;

  /* If any edges from predecessors are abnormal, antic_in is empty,
     so do nothing.  */
  if (block_has_abnormal_pred_edge)
    goto maybe_dump_sets;

  old = ANTIC_IN (block);
  ANTIC_OUT = bitmap_set_new ();

  /* If the block has no successors, ANTIC_OUT is empty.  */
  if (EDGE_COUNT (block->succs) == 0)
    ;
  /* If we have one successor, we could have some phi nodes to
     translate through.  */
  else if (single_succ_p (block))
    {
      e = single_succ_edge (block);
      gcc_assert (BB_VISITED (e->dest));
      phi_translate_set (ANTIC_OUT, ANTIC_IN (e->dest), e);
    }
  /* If we have multiple successors, we take the intersection of all of
     them.  Note that in the case of loop exit phi nodes, we may have
     phis to translate through.  */
  else
    {
      size_t i;
      edge first = NULL;

      auto_vec<edge> worklist (EDGE_COUNT (block->succs));
      FOR_EACH_EDGE (e, ei, block->succs)
	{
	  if (!first
	      && BB_VISITED (e->dest))
	    first = e;
	  else if (BB_VISITED (e->dest))
	    worklist.quick_push (e);
	  else
	    {
	      /* Unvisited successors get their ANTIC_IN replaced by the
		 maximal set to arrive at a maximum ANTIC_IN solution.
		 We can ignore them in the intersection operation and thus
		 need not explicitely represent that maximum solution.  */
	      if (dump_file && (dump_flags & TDF_DETAILS))
		fprintf (dump_file, "ANTIC_IN is MAX on %d->%d\n",
			 e->src->index, e->dest->index);
	    }
	}

      /* Of multiple successors we have to have visited one already
         which is guaranteed by iteration order.  */
      gcc_assert (first != NULL);

      phi_translate_set (ANTIC_OUT, ANTIC_IN (first->dest), first);

      /* If we have multiple successors we need to intersect the ANTIC_OUT
         sets.  For values that's a simple intersection but for
	 expressions it is a union.  Given we want to have a single
	 expression per value in our sets we have to canonicalize.
	 Avoid randomness and running into cycles like for PR82129 and
	 canonicalize the expression we choose to the one with the
	 lowest id.  This requires we actually compute the union first.  */
      FOR_EACH_VEC_ELT (worklist, i, e)
	{
	  if (!gimple_seq_empty_p (phi_nodes (e->dest)))
	    {
	      bitmap_set_t tmp = bitmap_set_new ();
	      phi_translate_set (tmp, ANTIC_IN (e->dest), e);
	      bitmap_and_into (&ANTIC_OUT->values, &tmp->values);
	      bitmap_ior_into (&ANTIC_OUT->expressions, &tmp->expressions);
	      bitmap_set_free (tmp);
	    }
	  else
	    {
	      bitmap_and_into (&ANTIC_OUT->values, &ANTIC_IN (e->dest)->values);
	      bitmap_ior_into (&ANTIC_OUT->expressions,
			       &ANTIC_IN (e->dest)->expressions);
	    }
	}
      if (! worklist.is_empty ())
	{
	  /* Prune expressions not in the value set.  */
	  bitmap_iterator bi;
	  unsigned int i;
	  unsigned int to_clear = -1U;
	  FOR_EACH_EXPR_ID_IN_SET (ANTIC_OUT, i, bi)
	    {
	      if (to_clear != -1U)
		{
		  bitmap_clear_bit (&ANTIC_OUT->expressions, to_clear);
		  to_clear = -1U;
		}
	      pre_expr expr = expression_for_id (i);
	      unsigned int value_id = get_expr_value_id (expr);
	      if (!bitmap_bit_p (&ANTIC_OUT->values, value_id))
		to_clear = i;
	    }
	  if (to_clear != -1U)
	    bitmap_clear_bit (&ANTIC_OUT->expressions, to_clear);
	}
    }

  /* Prune expressions that are clobbered in block and thus become
     invalid if translated from ANTIC_OUT to ANTIC_IN.  */
  prune_clobbered_mems (ANTIC_OUT, block);

  /* Generate ANTIC_OUT - TMP_GEN.  */
  S = bitmap_set_subtract_expressions (ANTIC_OUT, TMP_GEN (block));

  /* Start ANTIC_IN with EXP_GEN - TMP_GEN.  */
  ANTIC_IN (block) = bitmap_set_subtract_expressions (EXP_GEN (block),
						      TMP_GEN (block));

  /* Then union in the ANTIC_OUT - TMP_GEN values,
     to get ANTIC_OUT U EXP_GEN - TMP_GEN */
  bitmap_ior_into (&ANTIC_IN (block)->values, &S->values);
  bitmap_ior_into (&ANTIC_IN (block)->expressions, &S->expressions);

  /* clean (ANTIC_IN (block)) is defered to after the iteration converged
     because it can cause non-convergence, see for example PR81181.  */

  /* Intersect ANTIC_IN with the old ANTIC_IN.  This is required until
     we properly represent the maximum expression set, thus not prune
     values without expressions during the iteration.  */
  if (was_visited
      && bitmap_and_into (&ANTIC_IN (block)->values, &old->values))
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "warning: intersecting with old ANTIC_IN "
		 "shrinks the set\n");
      /* Prune expressions not in the value set.  */
      bitmap_iterator bi;
      unsigned int i;
      unsigned int to_clear = -1U;
      FOR_EACH_EXPR_ID_IN_SET (ANTIC_IN (block), i, bi)
	{
	  if (to_clear != -1U)
	    {
	      bitmap_clear_bit (&ANTIC_IN (block)->expressions, to_clear);
	      to_clear = -1U;
	    }
	  pre_expr expr = expression_for_id (i);
	  unsigned int value_id = get_expr_value_id (expr);
	  if (!bitmap_bit_p (&ANTIC_IN (block)->values, value_id))
	    to_clear = i;
	}
      if (to_clear != -1U)
	bitmap_clear_bit (&ANTIC_IN (block)->expressions, to_clear);
    }

  if (!bitmap_set_equal (old, ANTIC_IN (block)))
    changed = true;

 maybe_dump_sets:
  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      if (ANTIC_OUT)
	print_bitmap_set (dump_file, ANTIC_OUT, "ANTIC_OUT", block->index);

      if (changed)
	fprintf (dump_file, "[changed] ");
      print_bitmap_set (dump_file, ANTIC_IN (block), "ANTIC_IN",
			block->index);

      if (S)
	print_bitmap_set (dump_file, S, "S", block->index);
    }
  if (old)
    bitmap_set_free (old);
  if (S)
    bitmap_set_free (S);
  if (ANTIC_OUT)
    bitmap_set_free (ANTIC_OUT);
  return changed;
}

/* Compute PARTIAL_ANTIC for BLOCK.

   If succs(BLOCK) > 1 then
     PA_OUT[BLOCK] = value wise union of PA_IN[b] + all ANTIC_IN not
     in ANTIC_OUT for all succ(BLOCK)
   else if succs(BLOCK) == 1 then
     PA_OUT[BLOCK] = phi_translate (PA_IN[succ(BLOCK)])

   PA_IN[BLOCK] = clean(PA_OUT[BLOCK] - TMP_GEN[BLOCK] - ANTIC_IN[BLOCK])

*/
static void
compute_partial_antic_aux (basic_block block,
			   bool block_has_abnormal_pred_edge)
{
  bitmap_set_t old_PA_IN;
  bitmap_set_t PA_OUT;
  edge e;
  edge_iterator ei;
  unsigned long max_pa = PARAM_VALUE (PARAM_MAX_PARTIAL_ANTIC_LENGTH);

  old_PA_IN = PA_OUT = NULL;

  /* If any edges from predecessors are abnormal, antic_in is empty,
     so do nothing.  */
  if (block_has_abnormal_pred_edge)
    goto maybe_dump_sets;

  /* If there are too many partially anticipatable values in the
     block, phi_translate_set can take an exponential time: stop
     before the translation starts.  */
  if (max_pa
      && single_succ_p (block)
      && bitmap_count_bits (&PA_IN (single_succ (block))->values) > max_pa)
    goto maybe_dump_sets;

  old_PA_IN = PA_IN (block);
  PA_OUT = bitmap_set_new ();

  /* If the block has no successors, ANTIC_OUT is empty.  */
  if (EDGE_COUNT (block->succs) == 0)
    ;
  /* If we have one successor, we could have some phi nodes to
     translate through.  Note that we can't phi translate across DFS
     back edges in partial antic, because it uses a union operation on
     the successors.  For recurrences like IV's, we will end up
     generating a new value in the set on each go around (i + 3 (VH.1)
     VH.1 + 1 (VH.2), VH.2 + 1 (VH.3), etc), forever.  */
  else if (single_succ_p (block))
    {
      e = single_succ_edge (block);
      if (!(e->flags & EDGE_DFS_BACK))
	phi_translate_set (PA_OUT, PA_IN (e->dest), e);
    }
  /* If we have multiple successors, we take the union of all of
     them.  */
  else
    {
      size_t i;

      auto_vec<edge> worklist (EDGE_COUNT (block->succs));
      FOR_EACH_EDGE (e, ei, block->succs)
	{
	  if (e->flags & EDGE_DFS_BACK)
	    continue;
	  worklist.quick_push (e);
	}
      if (worklist.length () > 0)
	{
	  FOR_EACH_VEC_ELT (worklist, i, e)
	    {
	      unsigned int i;
	      bitmap_iterator bi;

	      FOR_EACH_EXPR_ID_IN_SET (ANTIC_IN (e->dest), i, bi)
		bitmap_value_insert_into_set (PA_OUT,
					      expression_for_id (i));
	      if (!gimple_seq_empty_p (phi_nodes (e->dest)))
		{
		  bitmap_set_t pa_in = bitmap_set_new ();
		  phi_translate_set (pa_in, PA_IN (e->dest), e);
		  FOR_EACH_EXPR_ID_IN_SET (pa_in, i, bi)
		    bitmap_value_insert_into_set (PA_OUT,
						  expression_for_id (i));
		  bitmap_set_free (pa_in);
		}
	      else
		FOR_EACH_EXPR_ID_IN_SET (PA_IN (e->dest), i, bi)
		  bitmap_value_insert_into_set (PA_OUT,
						expression_for_id (i));
	    }
	}
    }

  /* Prune expressions that are clobbered in block and thus become
     invalid if translated from PA_OUT to PA_IN.  */
  prune_clobbered_mems (PA_OUT, block);

  /* PA_IN starts with PA_OUT - TMP_GEN.
     Then we subtract things from ANTIC_IN.  */
  PA_IN (block) = bitmap_set_subtract_expressions (PA_OUT, TMP_GEN (block));

  /* For partial antic, we want to put back in the phi results, since
     we will properly avoid making them partially antic over backedges.  */
  bitmap_ior_into (&PA_IN (block)->values, &PHI_GEN (block)->values);
  bitmap_ior_into (&PA_IN (block)->expressions, &PHI_GEN (block)->expressions);

  /* PA_IN[block] = PA_IN[block] - ANTIC_IN[block] */
  bitmap_set_subtract_values (PA_IN (block), ANTIC_IN (block));

  clean (PA_IN (block), ANTIC_IN (block));

 maybe_dump_sets:
  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      if (PA_OUT)
	print_bitmap_set (dump_file, PA_OUT, "PA_OUT", block->index);

      print_bitmap_set (dump_file, PA_IN (block), "PA_IN", block->index);
    }
  if (old_PA_IN)
    bitmap_set_free (old_PA_IN);
  if (PA_OUT)
    bitmap_set_free (PA_OUT);
}

/* Compute ANTIC and partial ANTIC sets.  */

static void
compute_antic (void)
{
  bool changed = true;
  int num_iterations = 0;
  basic_block block;
  int i;
  edge_iterator ei;
  edge e;

  /* If any predecessor edges are abnormal, we punt, so antic_in is empty.
     We pre-build the map of blocks with incoming abnormal edges here.  */
  has_abnormal_preds = sbitmap_alloc (last_basic_block_for_fn (cfun));
  bitmap_clear (has_abnormal_preds);

  FOR_ALL_BB_FN (block, cfun)
    {
      BB_VISITED (block) = 0;

      FOR_EACH_EDGE (e, ei, block->preds)
	if (e->flags & EDGE_ABNORMAL)
	  {
	    bitmap_set_bit (has_abnormal_preds, block->index);
	    break;
	  }

      /* While we are here, give empty ANTIC_IN sets to each block.  */
      ANTIC_IN (block) = bitmap_set_new ();
      if (do_partial_partial)
	PA_IN (block) = bitmap_set_new ();
    }

  /* At the exit block we anticipate nothing.  */
  BB_VISITED (EXIT_BLOCK_PTR_FOR_FN (cfun)) = 1;

  /* For ANTIC computation we need a postorder that also guarantees that
     a block with a single successor is visited after its successor.
     RPO on the inverted CFG has this property.  */
  auto_vec<int, 20> postorder;
  inverted_post_order_compute (&postorder);

  auto_sbitmap worklist (last_basic_block_for_fn (cfun) + 1);
  bitmap_clear (worklist);
  FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
    bitmap_set_bit (worklist, e->src->index);
  while (changed)
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "Starting iteration %d\n", num_iterations);
      /* ???  We need to clear our PHI translation cache here as the
         ANTIC sets shrink and we restrict valid translations to
	 those having operands with leaders in ANTIC.  Same below
	 for PA ANTIC computation.  */
      num_iterations++;
      changed = false;
      for (i = postorder.length () - 1; i >= 0; i--)
	{
	  if (bitmap_bit_p (worklist, postorder[i]))
	    {
	      basic_block block = BASIC_BLOCK_FOR_FN (cfun, postorder[i]);
	      bitmap_clear_bit (worklist, block->index);
	      if (compute_antic_aux (block,
				     bitmap_bit_p (has_abnormal_preds,
						   block->index)))
		{
		  FOR_EACH_EDGE (e, ei, block->preds)
		    bitmap_set_bit (worklist, e->src->index);
		  changed = true;
		}
	    }
	}
      /* Theoretically possible, but *highly* unlikely.  */
      gcc_checking_assert (num_iterations < 500);
    }

  /* We have to clean after the dataflow problem converged as cleaning
     can cause non-convergence because it is based on expressions
     rather than values.  */
  FOR_EACH_BB_FN (block, cfun)
    clean (ANTIC_IN (block));

  statistics_histogram_event (cfun, "compute_antic iterations",
			      num_iterations);

  if (do_partial_partial)
    {
      /* For partial antic we ignore backedges and thus we do not need
         to perform any iteration when we process blocks in postorder.  */
      for (i = postorder.length () - 1; i >= 0; i--)
	{
	  basic_block block = BASIC_BLOCK_FOR_FN (cfun, postorder[i]);
	  compute_partial_antic_aux (block,
				     bitmap_bit_p (has_abnormal_preds,
						   block->index));
	}
    }

  sbitmap_free (has_abnormal_preds);
}


/* Inserted expressions are placed onto this worklist, which is used
   for performing quick dead code elimination of insertions we made
   that didn't turn out to be necessary.   */
static bitmap inserted_exprs;

/* The actual worker for create_component_ref_by_pieces.  */

static tree
create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref,
				  unsigned int *operand, gimple_seq *stmts)
{
  vn_reference_op_t currop = &ref->operands[*operand];
  tree genop;
  ++*operand;
  switch (currop->opcode)
    {
    case CALL_EXPR:
      gcc_unreachable ();

    case MEM_REF:
      {
	tree baseop = create_component_ref_by_pieces_1 (block, ref, operand,
							stmts);
	if (!baseop)
	  return NULL_TREE;
	tree offset = currop->op0;
	if (TREE_CODE (baseop) == ADDR_EXPR
	    && handled_component_p (TREE_OPERAND (baseop, 0)))
	  {
	    poly_int64 off;
	    tree base;
	    base = get_addr_base_and_unit_offset (TREE_OPERAND (baseop, 0),
						  &off);
	    gcc_assert (base);
	    offset = int_const_binop (PLUS_EXPR, offset,
				      build_int_cst (TREE_TYPE (offset),
						     off));
	    baseop = build_fold_addr_expr (base);
	  }
	genop = build2 (MEM_REF, currop->type, baseop, offset);
	MR_DEPENDENCE_CLIQUE (genop) = currop->clique;
	MR_DEPENDENCE_BASE (genop) = currop->base;
	REF_REVERSE_STORAGE_ORDER (genop) = currop->reverse;
	return genop;
      }

    case TARGET_MEM_REF:
      {
	tree genop0 = NULL_TREE, genop1 = NULL_TREE;
	vn_reference_op_t nextop = &ref->operands[++*operand];
	tree baseop = create_component_ref_by_pieces_1 (block, ref, operand,
							stmts);
	if (!baseop)
	  return NULL_TREE;
	if (currop->op0)
	  {
	    genop0 = find_or_generate_expression (block, currop->op0, stmts);
	    if (!genop0)
	      return NULL_TREE;
	  }
	if (nextop->op0)
	  {
	    genop1 = find_or_generate_expression (block, nextop->op0, stmts);
	    if (!genop1)
	      return NULL_TREE;
	  }
	genop = build5 (TARGET_MEM_REF, currop->type,
			baseop, currop->op2, genop0, currop->op1, genop1);

	MR_DEPENDENCE_CLIQUE (genop) = currop->clique;
	MR_DEPENDENCE_BASE (genop) = currop->base;
	return genop;
      }

    case ADDR_EXPR:
      if (currop->op0)
	{
	  gcc_assert (is_gimple_min_invariant (currop->op0));
	  return currop->op0;
	}
      /* Fallthrough.  */
    case REALPART_EXPR:
    case IMAGPART_EXPR:
    case VIEW_CONVERT_EXPR:
      {
	tree genop0 = create_component_ref_by_pieces_1 (block, ref, operand,
							stmts);
	if (!genop0)
	  return NULL_TREE;
	return fold_build1 (currop->opcode, currop->type, genop0);
      }

    case WITH_SIZE_EXPR:
      {
	tree genop0 = create_component_ref_by_pieces_1 (block, ref, operand,
							stmts);
	if (!genop0)
	  return NULL_TREE;
	tree genop1 = find_or_generate_expression (block, currop->op0, stmts);
	if (!genop1)
	  return NULL_TREE;
	return fold_build2 (currop->opcode, currop->type, genop0, genop1);
      }

    case BIT_FIELD_REF:
      {
	tree genop0 = create_component_ref_by_pieces_1 (block, ref, operand,
							stmts);
	if (!genop0)
	  return NULL_TREE;
	tree op1 = currop->op0;
	tree op2 = currop->op1;
	tree t = build3 (BIT_FIELD_REF, currop->type, genop0, op1, op2);
	REF_REVERSE_STORAGE_ORDER (t) = currop->reverse;
	return fold (t);
      }

      /* For array ref vn_reference_op's, operand 1 of the array ref
	 is op0 of the reference op and operand 3 of the array ref is
	 op1.  */
    case ARRAY_RANGE_REF:
    case ARRAY_REF:
      {
	tree genop0;
	tree genop1 = currop->op0;
	tree genop2 = currop->op1;
	tree genop3 = currop->op2;
	genop0 = create_component_ref_by_pieces_1 (block, ref, operand,
						   stmts);
	if (!genop0)
	  return NULL_TREE;
	genop1 = find_or_generate_expression (block, genop1, stmts);
	if (!genop1)
	  return NULL_TREE;
	if (genop2)
	  {
	    tree domain_type = TYPE_DOMAIN (TREE_TYPE (genop0));
	    /* Drop zero minimum index if redundant.  */
	    if (integer_zerop (genop2)
		&& (!domain_type
		    || integer_zerop (TYPE_MIN_VALUE (domain_type))))
	      genop2 = NULL_TREE;
	    else
	      {
		genop2 = find_or_generate_expression (block, genop2, stmts);
		if (!genop2)
		  return NULL_TREE;
	      }
	  }
	if (genop3)
	  {
	    tree elmt_type = TREE_TYPE (TREE_TYPE (genop0));
	    /* We can't always put a size in units of the element alignment
	       here as the element alignment may be not visible.  See
	       PR43783.  Simply drop the element size for constant
	       sizes.  */
	    if (TREE_CODE (genop3) == INTEGER_CST
		&& TREE_CODE (TYPE_SIZE_UNIT (elmt_type)) == INTEGER_CST
		&& wi::eq_p (wi::to_offset (TYPE_SIZE_UNIT (elmt_type)),
			     (wi::to_offset (genop3)
			      * vn_ref_op_align_unit (currop))))
	      genop3 = NULL_TREE;
	    else
	      {
		genop3 = find_or_generate_expression (block, genop3, stmts);
		if (!genop3)
		  return NULL_TREE;
	      }
	  }
	return build4 (currop->opcode, currop->type, genop0, genop1,
		       genop2, genop3);
      }
    case COMPONENT_REF:
      {
	tree op0;
	tree op1;
	tree genop2 = currop->op1;
	op0 = create_component_ref_by_pieces_1 (block, ref, operand, stmts);
	if (!op0)
	  return NULL_TREE;
	/* op1 should be a FIELD_DECL, which are represented by themselves.  */
	op1 = currop->op0;
	if (genop2)
	  {
	    genop2 = find_or_generate_expression (block, genop2, stmts);
	    if (!genop2)
	      return NULL_TREE;
	  }
	return fold_build3 (COMPONENT_REF, TREE_TYPE (op1), op0, op1, genop2);
      }

    case SSA_NAME:
      {
	genop = find_or_generate_expression (block, currop->op0, stmts);
	return genop;
      }
    case STRING_CST:
    case INTEGER_CST:
    case COMPLEX_CST:
    case VECTOR_CST:
    case REAL_CST:
    case CONSTRUCTOR:
    case VAR_DECL:
    case PARM_DECL:
    case CONST_DECL:
    case RESULT_DECL:
    case FUNCTION_DECL:
      return currop->op0;

    default:
      gcc_unreachable ();
    }
}

/* For COMPONENT_REF's and ARRAY_REF's, we can't have any intermediates for the
   COMPONENT_REF or MEM_REF or ARRAY_REF portion, because we'd end up with
   trying to rename aggregates into ssa form directly, which is a no no.

   Thus, this routine doesn't create temporaries, it just builds a
   single access expression for the array, calling
   find_or_generate_expression to build the innermost pieces.

   This function is a subroutine of create_expression_by_pieces, and
   should not be called on it's own unless you really know what you
   are doing.  */

static tree
create_component_ref_by_pieces (basic_block block, vn_reference_t ref,
				gimple_seq *stmts)
{
  unsigned int op = 0;
  return create_component_ref_by_pieces_1 (block, ref, &op, stmts);
}

/* Find a simple leader for an expression, or generate one using
   create_expression_by_pieces from a NARY expression for the value.
   BLOCK is the basic_block we are looking for leaders in.
   OP is the tree expression to find a leader for or generate.
   Returns the leader or NULL_TREE on failure.  */

static tree
find_or_generate_expression (basic_block block, tree op, gimple_seq *stmts)
{
  pre_expr expr = get_or_alloc_expr_for (op);
  unsigned int lookfor = get_expr_value_id (expr);
  pre_expr leader = bitmap_find_leader (AVAIL_OUT (block), lookfor);
  if (leader)
    {
      if (leader->kind == NAME)
	return PRE_EXPR_NAME (leader);
      else if (leader->kind == CONSTANT)
	return PRE_EXPR_CONSTANT (leader);

      /* Defer.  */
      return NULL_TREE;
    }

  /* It must be a complex expression, so generate it recursively.  Note
     that this is only necessary to handle gcc.dg/tree-ssa/ssa-pre28.c
     where the insert algorithm fails to insert a required expression.  */
  bitmap exprset = value_expressions[lookfor];
  bitmap_iterator bi;
  unsigned int i;
  EXECUTE_IF_SET_IN_BITMAP (exprset, 0, i, bi)
    {
      pre_expr temp = expression_for_id (i);
      /* We cannot insert random REFERENCE expressions at arbitrary
	 places.  We can insert NARYs which eventually re-materializes
	 its operand values.  */
      if (temp->kind == NARY)
	return create_expression_by_pieces (block, temp, stmts,
					    get_expr_type (expr));
    }

  /* Defer.  */
  return NULL_TREE;
}

/* Create an expression in pieces, so that we can handle very complex
   expressions that may be ANTIC, but not necessary GIMPLE.
   BLOCK is the basic block the expression will be inserted into,
   EXPR is the expression to insert (in value form)
   STMTS is a statement list to append the necessary insertions into.

   This function will die if we hit some value that shouldn't be
   ANTIC but is (IE there is no leader for it, or its components).
   The function returns NULL_TREE in case a different antic expression
   has to be inserted first.
   This function may also generate expressions that are themselves
   partially or fully redundant.  Those that are will be either made
   fully redundant during the next iteration of insert (for partially
   redundant ones), or eliminated by eliminate (for fully redundant
   ones).  */

static tree
create_expression_by_pieces (basic_block block, pre_expr expr,
			     gimple_seq *stmts, tree type)
{
  tree name;
  tree folded;
  gimple_seq forced_stmts = NULL;
  unsigned int value_id;
  gimple_stmt_iterator gsi;
  tree exprtype = type ? type : get_expr_type (expr);
  pre_expr nameexpr;
  gassign *newstmt;

  switch (expr->kind)
    {
    /* We may hit the NAME/CONSTANT case if we have to convert types
       that value numbering saw through.  */
    case NAME:
      folded = PRE_EXPR_NAME (expr);
      if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (folded))
	return NULL_TREE;
      if (useless_type_conversion_p (exprtype, TREE_TYPE (folded)))
	return folded;
      break;
    case CONSTANT:
      { 
	folded = PRE_EXPR_CONSTANT (expr);
	tree tem = fold_convert (exprtype, folded);
	if (is_gimple_min_invariant (tem))
	  return tem;
	break;
      }
    case REFERENCE:
      if (PRE_EXPR_REFERENCE (expr)->operands[0].opcode == CALL_EXPR)
	{
	  vn_reference_t ref = PRE_EXPR_REFERENCE (expr);
	  unsigned int operand = 1;
	  vn_reference_op_t currop = &ref->operands[0];
	  tree sc = NULL_TREE;
	  tree fn  = find_or_generate_expression (block, currop->op0, stmts);
	  if (!fn)
	    return NULL_TREE;
	  if (currop->op1)
	    {
	      sc = find_or_generate_expression (block, currop->op1, stmts);
	      if (!sc)
		return NULL_TREE;
	    }
	  auto_vec<tree> args (ref->operands.length () - 1);
	  while (operand < ref->operands.length ())
	    {
	      tree arg = create_component_ref_by_pieces_1 (block, ref,
							   &operand, stmts);
	      if (!arg)
		return NULL_TREE;
	      args.quick_push (arg);
	    }
	  gcall *call = gimple_build_call_vec (fn, args);
	  gimple_call_set_fntype (call, currop->type);
	  if (sc)
	    gimple_call_set_chain (call, sc);
	  tree forcedname = make_ssa_name (TREE_TYPE (currop->type));
	  gimple_call_set_lhs (call, forcedname);
	  /* There's no CCP pass after PRE which would re-compute alignment
	     information so make sure we re-materialize this here.  */
	  if (gimple_call_builtin_p (call, BUILT_IN_ASSUME_ALIGNED)
	      && args.length () - 2 <= 1
	      && tree_fits_uhwi_p (args[1])
	      && (args.length () != 3 || tree_fits_uhwi_p (args[2])))
	    {
	      unsigned HOST_WIDE_INT halign = tree_to_uhwi (args[1]);
	      unsigned HOST_WIDE_INT hmisalign
		= args.length () == 3 ? tree_to_uhwi (args[2]) : 0;
	      if ((halign & (halign - 1)) == 0
		  && (hmisalign & ~(halign - 1)) == 0)
		set_ptr_info_alignment (get_ptr_info (forcedname),
					halign, hmisalign);
	    }
	  gimple_set_vuse (call, BB_LIVE_VOP_ON_EXIT (block));
	  gimple_seq_add_stmt_without_update (&forced_stmts, call);
	  folded = forcedname;
	}
      else
	{
	  folded = create_component_ref_by_pieces (block,
						   PRE_EXPR_REFERENCE (expr),
						   stmts);
	  if (!folded)
	    return NULL_TREE;
	  name = make_temp_ssa_name (exprtype, NULL, "pretmp");
	  newstmt = gimple_build_assign (name, folded);
	  gimple_seq_add_stmt_without_update (&forced_stmts, newstmt);
	  gimple_set_vuse (newstmt, BB_LIVE_VOP_ON_EXIT (block));
	  folded = name;
	}
      break;
    case NARY:
      {
	vn_nary_op_t nary = PRE_EXPR_NARY (expr);
	tree *genop = XALLOCAVEC (tree, nary->length);
	unsigned i;
	for (i = 0; i < nary->length; ++i)
	  {
	    genop[i] = find_or_generate_expression (block, nary->op[i], stmts);
	    if (!genop[i])
	      return NULL_TREE;
	    /* Ensure genop[] is properly typed for POINTER_PLUS_EXPR.  It
	       may have conversions stripped.  */
	    if (nary->opcode == POINTER_PLUS_EXPR)
	      {
		if (i == 0)
		  genop[i] = gimple_convert (&forced_stmts,
					     nary->type, genop[i]);
		else if (i == 1)
		  genop[i] = gimple_convert (&forced_stmts,
					     sizetype, genop[i]);
	      }
	    else
	      genop[i] = gimple_convert (&forced_stmts,
					 TREE_TYPE (nary->op[i]), genop[i]);
	  }
	if (nary->opcode == CONSTRUCTOR)
	  {
	    vec<constructor_elt, va_gc> *elts = NULL;
	    for (i = 0; i < nary->length; ++i)
	      CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE, genop[i]);
	    folded = build_constructor (nary->type, elts);
	    name = make_temp_ssa_name (exprtype, NULL, "pretmp");
	    newstmt = gimple_build_assign (name, folded);
	    gimple_seq_add_stmt_without_update (&forced_stmts, newstmt);
	    folded = name;
	  }
	else
	  {
	    switch (nary->length)
	      {
	      case 1:
		folded = gimple_build (&forced_stmts, nary->opcode, nary->type,
				       genop[0]);
		break;
	      case 2:
		folded = gimple_build (&forced_stmts, nary->opcode, nary->type,
				       genop[0], genop[1]);
		break;
	      case 3:
		folded = gimple_build (&forced_stmts, nary->opcode, nary->type,
				       genop[0], genop[1], genop[2]);
		break;
	      default:
		gcc_unreachable ();
	      }
	  }
      }
      break;
    default:
      gcc_unreachable ();
    }

  folded = gimple_convert (&forced_stmts, exprtype, folded);

  /* If there is nothing to insert, return the simplified result.  */
  if (gimple_seq_empty_p (forced_stmts))
    return folded;
  /* If we simplified to a constant return it and discard eventually
     built stmts.  */
  if (is_gimple_min_invariant (folded))
    {
      gimple_seq_discard (forced_stmts);
      return folded;
    }
  /* Likewise if we simplified to sth not queued for insertion.  */
  bool found = false;
  gsi = gsi_last (forced_stmts);
  for (; !gsi_end_p (gsi); gsi_prev (&gsi))
    {
      gimple *stmt = gsi_stmt (gsi);
      tree forcedname = gimple_get_lhs (stmt);
      if (forcedname == folded)
	{
	  found = true;
	  break;
	}
    }
  if (! found)
    {
      gimple_seq_discard (forced_stmts);
      return folded;
    }
  gcc_assert (TREE_CODE (folded) == SSA_NAME);

  /* If we have any intermediate expressions to the value sets, add them
     to the value sets and chain them in the instruction stream.  */
  if (forced_stmts)
    {
      gsi = gsi_start (forced_stmts);
      for (; !gsi_end_p (gsi); gsi_next (&gsi))
	{
	  gimple *stmt = gsi_stmt (gsi);
	  tree forcedname = gimple_get_lhs (stmt);
	  pre_expr nameexpr;

	  if (forcedname != folded)
	    {
	      VN_INFO (forcedname)->valnum = forcedname;
	      VN_INFO (forcedname)->value_id = get_next_value_id ();
	      nameexpr = get_or_alloc_expr_for_name (forcedname);
	      add_to_value (VN_INFO (forcedname)->value_id, nameexpr);
	      bitmap_value_replace_in_set (NEW_SETS (block), nameexpr);
	      bitmap_value_replace_in_set (AVAIL_OUT (block), nameexpr);
	    }

	  bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (forcedname));
	}
      gimple_seq_add_seq (stmts, forced_stmts);
    }

  name = folded;

  /* Fold the last statement.  */
  gsi = gsi_last (*stmts);
  if (fold_stmt_inplace (&gsi))
    update_stmt (gsi_stmt (gsi));

  /* Add a value number to the temporary.
     The value may already exist in either NEW_SETS, or AVAIL_OUT, because
     we are creating the expression by pieces, and this particular piece of
     the expression may have been represented.  There is no harm in replacing
     here.  */
  value_id = get_expr_value_id (expr);
  VN_INFO (name)->value_id = value_id;
  VN_INFO (name)->valnum = vn_valnum_from_value_id (value_id);
  if (VN_INFO (name)->valnum == NULL_TREE)
    VN_INFO (name)->valnum = name;
  gcc_assert (VN_INFO (name)->valnum != NULL_TREE);
  nameexpr = get_or_alloc_expr_for_name (name);
  add_to_value (value_id, nameexpr);
  if (NEW_SETS (block))
    bitmap_value_replace_in_set (NEW_SETS (block), nameexpr);
  bitmap_value_replace_in_set (AVAIL_OUT (block), nameexpr);

  pre_stats.insertions++;
  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Inserted ");
      print_gimple_stmt (dump_file, gsi_stmt (gsi_last (*stmts)), 0);
      fprintf (dump_file, " in predecessor %d (%04d)\n",
	       block->index, value_id);
    }

  return name;
}


/* Insert the to-be-made-available values of expression EXPRNUM for each
   predecessor, stored in AVAIL, into the predecessors of BLOCK, and
   merge the result with a phi node, given the same value number as
   NODE.  Return true if we have inserted new stuff.  */

static bool
insert_into_preds_of_block (basic_block block, unsigned int exprnum,
			    vec<pre_expr> avail)
{
  pre_expr expr = expression_for_id (exprnum);
  pre_expr newphi;
  unsigned int val = get_expr_value_id (expr);
  edge pred;
  bool insertions = false;
  bool nophi = false;
  basic_block bprime;
  pre_expr eprime;
  edge_iterator ei;
  tree type = get_expr_type (expr);
  tree temp;
  gphi *phi;

  /* Make sure we aren't creating an induction variable.  */
  if (bb_loop_depth (block) > 0 && EDGE_COUNT (block->preds) == 2)
    {
      bool firstinsideloop = false;
      bool secondinsideloop = false;
      firstinsideloop = flow_bb_inside_loop_p (block->loop_father,
					       EDGE_PRED (block, 0)->src);
      secondinsideloop = flow_bb_inside_loop_p (block->loop_father,
						EDGE_PRED (block, 1)->src);
      /* Induction variables only have one edge inside the loop.  */
      if ((firstinsideloop ^ secondinsideloop)
	  && expr->kind != REFERENCE)
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file, "Skipping insertion of phi for partial redundancy: Looks like an induction variable\n");
	  nophi = true;
	}
    }

  /* Make the necessary insertions.  */
  FOR_EACH_EDGE (pred, ei, block->preds)
    {
      gimple_seq stmts = NULL;
      tree builtexpr;
      bprime = pred->src;
      eprime = avail[pred->dest_idx];
      builtexpr = create_expression_by_pieces (bprime, eprime,
					       &stmts, type);
      gcc_assert (!(pred->flags & EDGE_ABNORMAL));
      if (!gimple_seq_empty_p (stmts))
	{
	  basic_block new_bb = gsi_insert_seq_on_edge_immediate (pred, stmts);
	  gcc_assert (! new_bb);
	  insertions = true;
	}
      if (!builtexpr)
	{
	  /* We cannot insert a PHI node if we failed to insert
	     on one edge.  */
	  nophi = true;
	  continue;
	}
      if (is_gimple_min_invariant (builtexpr))
	avail[pred->dest_idx] = get_or_alloc_expr_for_constant (builtexpr);
      else
	avail[pred->dest_idx] = get_or_alloc_expr_for_name (builtexpr);
    }
  /* If we didn't want a phi node, and we made insertions, we still have
     inserted new stuff, and thus return true.  If we didn't want a phi node,
     and didn't make insertions, we haven't added anything new, so return
     false.  */
  if (nophi && insertions)
    return true;
  else if (nophi && !insertions)
    return false;

  /* Now build a phi for the new variable.  */
  temp = make_temp_ssa_name (type, NULL, "prephitmp");
  phi = create_phi_node (temp, block);

  VN_INFO (temp)->value_id = val;
  VN_INFO (temp)->valnum = vn_valnum_from_value_id (val);
  if (VN_INFO (temp)->valnum == NULL_TREE)
    VN_INFO (temp)->valnum = temp;
  bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (temp));
  FOR_EACH_EDGE (pred, ei, block->preds)
    {
      pre_expr ae = avail[pred->dest_idx];
      gcc_assert (get_expr_type (ae) == type
		  || useless_type_conversion_p (type, get_expr_type (ae)));
      if (ae->kind == CONSTANT)
	add_phi_arg (phi, unshare_expr (PRE_EXPR_CONSTANT (ae)),
		     pred, UNKNOWN_LOCATION);
      else
	add_phi_arg (phi, PRE_EXPR_NAME (ae), pred, UNKNOWN_LOCATION);
    }

  newphi = get_or_alloc_expr_for_name (temp);
  add_to_value (val, newphi);

  /* The value should *not* exist in PHI_GEN, or else we wouldn't be doing
     this insertion, since we test for the existence of this value in PHI_GEN
     before proceeding with the partial redundancy checks in insert_aux.

     The value may exist in AVAIL_OUT, in particular, it could be represented
     by the expression we are trying to eliminate, in which case we want the
     replacement to occur.  If it's not existing in AVAIL_OUT, we want it
     inserted there.

     Similarly, to the PHI_GEN case, the value should not exist in NEW_SETS of
     this block, because if it did, it would have existed in our dominator's
     AVAIL_OUT, and would have been skipped due to the full redundancy check.
  */

  bitmap_insert_into_set (PHI_GEN (block), newphi);
  bitmap_value_replace_in_set (AVAIL_OUT (block),
			       newphi);
  bitmap_insert_into_set (NEW_SETS (block),
			  newphi);

  /* If we insert a PHI node for a conversion of another PHI node
     in the same basic-block try to preserve range information.
     This is important so that followup loop passes receive optimal
     number of iteration analysis results.  See PR61743.  */
  if (expr->kind == NARY
      && CONVERT_EXPR_CODE_P (expr->u.nary->opcode)
      && TREE_CODE (expr->u.nary->op[0]) == SSA_NAME
      && gimple_bb (SSA_NAME_DEF_STMT (expr->u.nary->op[0])) == block
      && INTEGRAL_TYPE_P (type)
      && INTEGRAL_TYPE_P (TREE_TYPE (expr->u.nary->op[0]))
      && (TYPE_PRECISION (type)
	  >= TYPE_PRECISION (TREE_TYPE (expr->u.nary->op[0])))
      && SSA_NAME_RANGE_INFO (expr->u.nary->op[0]))
    {
      wide_int min, max;
      if (get_range_info (expr->u.nary->op[0], &min, &max) == VR_RANGE
	  && !wi::neg_p (min, SIGNED)
	  && !wi::neg_p (max, SIGNED))
	/* Just handle extension and sign-changes of all-positive ranges.  */
	set_range_info (temp,
			SSA_NAME_RANGE_TYPE (expr->u.nary->op[0]),
			wide_int_storage::from (min, TYPE_PRECISION (type),
						TYPE_SIGN (type)),
			wide_int_storage::from (max, TYPE_PRECISION (type),
						TYPE_SIGN (type)));
    }

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Created phi ");
      print_gimple_stmt (dump_file, phi, 0);
      fprintf (dump_file, " in block %d (%04d)\n", block->index, val);
    }
  pre_stats.phis++;
  return true;
}



/* Perform insertion of partially redundant or hoistable values.
   For BLOCK, do the following:
   1.  Propagate the NEW_SETS of the dominator into the current block.
   If the block has multiple predecessors,
       2a. Iterate over the ANTIC expressions for the block to see if
	   any of them are partially redundant.
       2b. If so, insert them into the necessary predecessors to make
	   the expression fully redundant.
       2c. Insert a new PHI merging the values of the predecessors.
       2d. Insert the new PHI, and the new expressions, into the
	   NEW_SETS set.
   If the block has multiple successors,
       3a. Iterate over the ANTIC values for the block to see if
	   any of them are good candidates for hoisting.
       3b. If so, insert expressions computing the values in BLOCK,
	   and add the new expressions into the NEW_SETS set.
   4. Recursively call ourselves on the dominator children of BLOCK.

   Steps 1, 2a, and 4 are done by insert_aux. 2b, 2c and 2d are done by
   do_pre_regular_insertion and do_partial_insertion.  3a and 3b are
   done in do_hoist_insertion.
*/

static bool
do_pre_regular_insertion (basic_block block, basic_block dom)
{
  bool new_stuff = false;
  vec<pre_expr> exprs;
  pre_expr expr;
  auto_vec<pre_expr> avail;
  int i;

  exprs = sorted_array_from_bitmap_set (ANTIC_IN (block));
  avail.safe_grow (EDGE_COUNT (block->preds));

  FOR_EACH_VEC_ELT (exprs, i, expr)
    {
      if (expr->kind == NARY
	  || expr->kind == REFERENCE)
	{
	  unsigned int val;
	  bool by_some = false;
	  bool cant_insert = false;
	  bool all_same = true;
	  pre_expr first_s = NULL;
	  edge pred;
	  basic_block bprime;
	  pre_expr eprime = NULL;
	  edge_iterator ei;
	  pre_expr edoubleprime = NULL;
	  bool do_insertion = false;

	  val = get_expr_value_id (expr);
	  if (bitmap_set_contains_value (PHI_GEN (block), val))
	    continue;
	  if (bitmap_set_contains_value (AVAIL_OUT (dom), val))
	    {
	      if (dump_file && (dump_flags & TDF_DETAILS))
		{
		  fprintf (dump_file, "Found fully redundant value: ");
		  print_pre_expr (dump_file, expr);
		  fprintf (dump_file, "\n");
		}
	      continue;
	    }

	  FOR_EACH_EDGE (pred, ei, block->preds)
	    {
	      unsigned int vprime;

	      /* We should never run insertion for the exit block
	         and so not come across fake pred edges.  */
	      gcc_assert (!(pred->flags & EDGE_FAKE));
	      bprime = pred->src;
	      /* We are looking at ANTIC_OUT of bprime.  */
	      eprime = phi_translate (NULL, expr, ANTIC_IN (block), NULL, pred);

	      /* eprime will generally only be NULL if the
		 value of the expression, translated
		 through the PHI for this predecessor, is
		 undefined.  If that is the case, we can't
		 make the expression fully redundant,
		 because its value is undefined along a
		 predecessor path.  We can thus break out
		 early because it doesn't matter what the
		 rest of the results are.  */
	      if (eprime == NULL)
		{
		  avail[pred->dest_idx] = NULL;
		  cant_insert = true;
		  break;
		}

	      vprime = get_expr_value_id (eprime);
	      edoubleprime = bitmap_find_leader (AVAIL_OUT (bprime),
						 vprime);
	      if (edoubleprime == NULL)
		{
		  avail[pred->dest_idx] = eprime;
		  all_same = false;
		}
	      else
		{
		  avail[pred->dest_idx] = edoubleprime;
		  by_some = true;
		  /* We want to perform insertions to remove a redundancy on
		     a path in the CFG we want to optimize for speed.  */
		  if (optimize_edge_for_speed_p (pred))
		    do_insertion = true;
		  if (first_s == NULL)
		    first_s = edoubleprime;
		  else if (!pre_expr_d::equal (first_s, edoubleprime))
		    all_same = false;
		}
	    }
	  /* If we can insert it, it's not the same value
	     already existing along every predecessor, and
	     it's defined by some predecessor, it is
	     partially redundant.  */
	  if (!cant_insert && !all_same && by_some)
	    {
	      if (!do_insertion)
		{
		  if (dump_file && (dump_flags & TDF_DETAILS))
		    {
		      fprintf (dump_file, "Skipping partial redundancy for "
			       "expression ");
		      print_pre_expr (dump_file, expr);
		      fprintf (dump_file, " (%04d), no redundancy on to be "
			       "optimized for speed edge\n", val);
		    }
		}
	      else if (dbg_cnt (treepre_insert))
		{
		  if (dump_file && (dump_flags & TDF_DETAILS))
		    {
		      fprintf (dump_file, "Found partial redundancy for "
			       "expression ");
		      print_pre_expr (dump_file, expr);
		      fprintf (dump_file, " (%04d)\n",
			       get_expr_value_id (expr));
		    }
		  if (insert_into_preds_of_block (block,
						  get_expression_id (expr),
						  avail))
		    new_stuff = true;
		}
	    }
	  /* If all edges produce the same value and that value is
	     an invariant, then the PHI has the same value on all
	     edges.  Note this.  */
	  else if (!cant_insert && all_same)
	    {
	      gcc_assert (edoubleprime->kind == CONSTANT
			  || edoubleprime->kind == NAME);

	      tree temp = make_temp_ssa_name (get_expr_type (expr),
					      NULL, "pretmp");
	      gassign *assign
		= gimple_build_assign (temp,
				       edoubleprime->kind == CONSTANT ?
				       PRE_EXPR_CONSTANT (edoubleprime) :
				       PRE_EXPR_NAME (edoubleprime));
	      gimple_stmt_iterator gsi = gsi_after_labels (block);
	      gsi_insert_before (&gsi, assign, GSI_NEW_STMT);

	      VN_INFO (temp)->value_id = val;
	      VN_INFO (temp)->valnum = vn_valnum_from_value_id (val);
	      if (VN_INFO (temp)->valnum == NULL_TREE)
		VN_INFO (temp)->valnum = temp;
	      bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (temp));
	      pre_expr newe = get_or_alloc_expr_for_name (temp);
	      add_to_value (val, newe);
	      bitmap_value_replace_in_set (AVAIL_OUT (block), newe);
	      bitmap_insert_into_set (NEW_SETS (block), newe);
	    }
	}
    }

  exprs.release ();
  return new_stuff;
}


/* Perform insertion for partially anticipatable expressions.  There
   is only one case we will perform insertion for these.  This case is
   if the expression is partially anticipatable, and fully available.
   In this case, we know that putting it earlier will enable us to
   remove the later computation.  */

static bool
do_pre_partial_partial_insertion (basic_block block, basic_block dom)
{
  bool new_stuff = false;
  vec<pre_expr> exprs;
  pre_expr expr;
  auto_vec<pre_expr> avail;
  int i;

  exprs = sorted_array_from_bitmap_set (PA_IN (block));
  avail.safe_grow (EDGE_COUNT (block->preds));

  FOR_EACH_VEC_ELT (exprs, i, expr)
    {
      if (expr->kind == NARY
	  || expr->kind == REFERENCE)
	{
	  unsigned int val;
	  bool by_all = true;
	  bool cant_insert = false;
	  edge pred;
	  basic_block bprime;
	  pre_expr eprime = NULL;
	  edge_iterator ei;

	  val = get_expr_value_id (expr);
	  if (bitmap_set_contains_value (PHI_GEN (block), val))
	    continue;
	  if (bitmap_set_contains_value (AVAIL_OUT (dom), val))
	    continue;

	  FOR_EACH_EDGE (pred, ei, block->preds)
	    {
	      unsigned int vprime;
	      pre_expr edoubleprime;

	      /* We should never run insertion for the exit block
	         and so not come across fake pred edges.  */
	      gcc_assert (!(pred->flags & EDGE_FAKE));
	      bprime = pred->src;
	      eprime = phi_translate (NULL, expr, ANTIC_IN (block),
				      PA_IN (block), pred);

	      /* eprime will generally only be NULL if the
		 value of the expression, translated
		 through the PHI for this predecessor, is
		 undefined.  If that is the case, we can't
		 make the expression fully redundant,
		 because its value is undefined along a
		 predecessor path.  We can thus break out
		 early because it doesn't matter what the
		 rest of the results are.  */
	      if (eprime == NULL)
		{
		  avail[pred->dest_idx] = NULL;
		  cant_insert = true;
		  break;
		}

	      vprime = get_expr_value_id (eprime);
	      edoubleprime = bitmap_find_leader (AVAIL_OUT (bprime), vprime);
	      avail[pred->dest_idx] = edoubleprime;
	      if (edoubleprime == NULL)
		{
		  by_all = false;
		  break;
		}
	    }

	  /* If we can insert it, it's not the same value
	     already existing along every predecessor, and
	     it's defined by some predecessor, it is
	     partially redundant.  */
	  if (!cant_insert && by_all)
	    {
	      edge succ;
	      bool do_insertion = false;

	      /* Insert only if we can remove a later expression on a path
		 that we want to optimize for speed.
		 The phi node that we will be inserting in BLOCK is not free,
		 and inserting it for the sake of !optimize_for_speed successor
		 may cause regressions on the speed path.  */
	      FOR_EACH_EDGE (succ, ei, block->succs)
		{
		  if (bitmap_set_contains_value (PA_IN (succ->dest), val)
		      || bitmap_set_contains_value (ANTIC_IN (succ->dest), val))
		    {
		      if (optimize_edge_for_speed_p (succ))
			do_insertion = true;
		    }
		}

	      if (!do_insertion)
		{
		  if (dump_file && (dump_flags & TDF_DETAILS))
		    {
		      fprintf (dump_file, "Skipping partial partial redundancy "
			       "for expression ");
		      print_pre_expr (dump_file, expr);
		      fprintf (dump_file, " (%04d), not (partially) anticipated "
			       "on any to be optimized for speed edges\n", val);
		    }
		}
	      else if (dbg_cnt (treepre_insert))
		{
		  pre_stats.pa_insert++;
		  if (dump_file && (dump_flags & TDF_DETAILS))
		    {
		      fprintf (dump_file, "Found partial partial redundancy "
			       "for expression ");
		      print_pre_expr (dump_file, expr);
		      fprintf (dump_file, " (%04d)\n",
			       get_expr_value_id (expr));
		    }
		  if (insert_into_preds_of_block (block,
						  get_expression_id (expr),
						  avail))
		    new_stuff = true;
		}	   
	    } 
	}
    }

  exprs.release ();
  return new_stuff;
}

/* Insert expressions in BLOCK to compute hoistable values up.
   Return TRUE if something was inserted, otherwise return FALSE.
   The caller has to make sure that BLOCK has at least two successors.  */

static bool
do_hoist_insertion (basic_block block)
{
  edge e;
  edge_iterator ei;
  bool new_stuff = false;
  unsigned i;
  gimple_stmt_iterator last;

  /* At least two successors, or else...  */
  gcc_assert (EDGE_COUNT (block->succs) >= 2);

  /* Check that all successors of BLOCK are dominated by block.
     We could use dominated_by_p() for this, but actually there is a much
     quicker check: any successor that is dominated by BLOCK can't have
     more than one predecessor edge.  */
  FOR_EACH_EDGE (e, ei, block->succs)
    if (! single_pred_p (e->dest))
      return false;

  /* Determine the insertion point.  If we cannot safely insert before
     the last stmt if we'd have to, bail out.  */
  last = gsi_last_bb (block);
  if (!gsi_end_p (last)
      && !is_ctrl_stmt (gsi_stmt (last))
      && stmt_ends_bb_p (gsi_stmt (last)))
    return false;

  /* Compute the set of hoistable expressions from ANTIC_IN.  First compute
     hoistable values.  */
  bitmap_set hoistable_set;

  /* A hoistable value must be in ANTIC_IN(block)
     but not in AVAIL_OUT(BLOCK).  */
  bitmap_initialize (&hoistable_set.values, &grand_bitmap_obstack);
  bitmap_and_compl (&hoistable_set.values,
		    &ANTIC_IN (block)->values, &AVAIL_OUT (block)->values);

  /* Short-cut for a common case: hoistable_set is empty.  */
  if (bitmap_empty_p (&hoistable_set.values))
    return false;

  /* Compute which of the hoistable values is in AVAIL_OUT of
     at least one of the successors of BLOCK.  */
  bitmap_head availout_in_some;
  bitmap_initialize (&availout_in_some, &grand_bitmap_obstack);
  FOR_EACH_EDGE (e, ei, block->succs)
    /* Do not consider expressions solely because their availability
       on loop exits.  They'd be ANTIC-IN throughout the whole loop
       and thus effectively hoisted across loops by combination of
       PRE and hoisting.  */
    if (! loop_exit_edge_p (block->loop_father, e))
      bitmap_ior_and_into (&availout_in_some, &hoistable_set.values,
			   &AVAIL_OUT (e->dest)->values);
  bitmap_clear (&hoistable_set.values);

  /* Short-cut for a common case: availout_in_some is empty.  */
  if (bitmap_empty_p (&availout_in_some))
    return false;

  /* Hack hoitable_set in-place so we can use sorted_array_from_bitmap_set.  */
  bitmap_move (&hoistable_set.values, &availout_in_some);
  hoistable_set.expressions = ANTIC_IN (block)->expressions;

  /* Now finally construct the topological-ordered expression set.  */
  vec<pre_expr> exprs = sorted_array_from_bitmap_set (&hoistable_set);

  bitmap_clear (&hoistable_set.values);

  /* If there are candidate values for hoisting, insert expressions
     strategically to make the hoistable expressions fully redundant.  */
  pre_expr expr;
  FOR_EACH_VEC_ELT (exprs, i, expr)
    {
      /* While we try to sort expressions topologically above the
         sorting doesn't work out perfectly.  Catch expressions we
	 already inserted.  */
      unsigned int value_id = get_expr_value_id (expr);
      if (bitmap_set_contains_value (AVAIL_OUT (block), value_id))
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file,
		       "Already inserted expression for ");
	      print_pre_expr (dump_file, expr);
	      fprintf (dump_file, " (%04d)\n", value_id);
	    }
	  continue;
	}

      /* OK, we should hoist this value.  Perform the transformation.  */
      pre_stats.hoist_insert++;
      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file,
		   "Inserting expression in block %d for code hoisting: ",
		   block->index);
	  print_pre_expr (dump_file, expr);
	  fprintf (dump_file, " (%04d)\n", value_id);
	}

      gimple_seq stmts = NULL;
      tree res = create_expression_by_pieces (block, expr, &stmts,
					      get_expr_type (expr));

      /* Do not return true if expression creation ultimately
         did not insert any statements.  */
      if (gimple_seq_empty_p (stmts))
	res = NULL_TREE;
      else
	{
	  if (gsi_end_p (last) || is_ctrl_stmt (gsi_stmt (last)))
	    gsi_insert_seq_before (&last, stmts, GSI_SAME_STMT);
	  else
	    gsi_insert_seq_after (&last, stmts, GSI_NEW_STMT);
	}

      /* Make sure to not return true if expression creation ultimately
         failed but also make sure to insert any stmts produced as they
	 are tracked in inserted_exprs.  */
      if (! res)
	continue;

      new_stuff = true;
    }

  exprs.release ();

  return new_stuff;
}

/* Perform insertion of partially redundant and hoistable values.  */

static void
insert (void)
{
  basic_block bb;

  FOR_ALL_BB_FN (bb, cfun)
    NEW_SETS (bb) = bitmap_set_new ();

  int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (cfun));
  int rpo_num = pre_and_rev_post_order_compute (NULL, rpo, false);

  int num_iterations = 0;
  bool changed;
  do
    {
      num_iterations++;
      if (dump_file && dump_flags & TDF_DETAILS)
	fprintf (dump_file, "Starting insert iteration %d\n", num_iterations);

      changed = false;
      for (int idx = 0; idx < rpo_num; ++idx)
	{
	  basic_block block = BASIC_BLOCK_FOR_FN (cfun, rpo[idx]);
	  basic_block dom = get_immediate_dominator (CDI_DOMINATORS, block);
	  if (dom)
	    {
	      unsigned i;
	      bitmap_iterator bi;
	      bitmap_set_t newset;

	      /* First, update the AVAIL_OUT set with anything we may have
		 inserted higher up in the dominator tree.  */
	      newset = NEW_SETS (dom);
	      if (newset)
		{
		  /* Note that we need to value_replace both NEW_SETS, and
		     AVAIL_OUT. For both the case of NEW_SETS, the value may be
		     represented by some non-simple expression here that we want
		     to replace it with.  */
		  FOR_EACH_EXPR_ID_IN_SET (newset, i, bi)
		    {
		      pre_expr expr = expression_for_id (i);
		      bitmap_value_replace_in_set (NEW_SETS (block), expr);
		      bitmap_value_replace_in_set (AVAIL_OUT (block), expr);
		    }
		}

	      /* Insert expressions for partial redundancies.  */
	      if (flag_tree_pre && !single_pred_p (block))
		{
		  changed |= do_pre_regular_insertion (block, dom);
		  if (do_partial_partial)
		    changed |= do_pre_partial_partial_insertion (block, dom);
		}

	      /* Insert expressions for hoisting.  */
	      if (flag_code_hoisting && EDGE_COUNT (block->succs) >= 2)
		changed |= do_hoist_insertion (block);
	    }
	}

      /* Clear the NEW sets before the next iteration.  We have already
	 fully propagated its contents.  */
      if (changed)
	FOR_ALL_BB_FN (bb, cfun)
	  bitmap_set_free (NEW_SETS (bb));
    }
  while (changed);

  statistics_histogram_event (cfun, "insert iterations", num_iterations);

  free (rpo);
}


/* Compute the AVAIL set for all basic blocks.

   This function performs value numbering of the statements in each basic
   block.  The AVAIL sets are built from information we glean while doing
   this value numbering, since the AVAIL sets contain only one entry per
   value.

   AVAIL_IN[BLOCK] = AVAIL_OUT[dom(BLOCK)].
   AVAIL_OUT[BLOCK] = AVAIL_IN[BLOCK] U PHI_GEN[BLOCK] U TMP_GEN[BLOCK].  */

static void
compute_avail (void)
{

  basic_block block, son;
  basic_block *worklist;
  size_t sp = 0;
  unsigned i;
  tree name;

  /* We pretend that default definitions are defined in the entry block.
     This includes function arguments and the static chain decl.  */
  FOR_EACH_SSA_NAME (i, name, cfun)
    {
      pre_expr e;
      if (!SSA_NAME_IS_DEFAULT_DEF (name)
	  || has_zero_uses (name)
	  || virtual_operand_p (name))
	continue;

      e = get_or_alloc_expr_for_name (name);
      add_to_value (get_expr_value_id (e), e);
      bitmap_insert_into_set (TMP_GEN (ENTRY_BLOCK_PTR_FOR_FN (cfun)), e);
      bitmap_value_insert_into_set (AVAIL_OUT (ENTRY_BLOCK_PTR_FOR_FN (cfun)),
				    e);
    }

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      print_bitmap_set (dump_file, TMP_GEN (ENTRY_BLOCK_PTR_FOR_FN (cfun)),
			"tmp_gen", ENTRY_BLOCK);
      print_bitmap_set (dump_file, AVAIL_OUT (ENTRY_BLOCK_PTR_FOR_FN (cfun)),
			"avail_out", ENTRY_BLOCK);
    }

  /* Allocate the worklist.  */
  worklist = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun));

  /* Seed the algorithm by putting the dominator children of the entry
     block on the worklist.  */
  for (son = first_dom_son (CDI_DOMINATORS, ENTRY_BLOCK_PTR_FOR_FN (cfun));
       son;
       son = next_dom_son (CDI_DOMINATORS, son))
    worklist[sp++] = son;

  BB_LIVE_VOP_ON_EXIT (ENTRY_BLOCK_PTR_FOR_FN (cfun))
    = ssa_default_def (cfun, gimple_vop (cfun));

  /* Loop until the worklist is empty.  */
  while (sp)
    {
      gimple *stmt;
      basic_block dom;

      /* Pick a block from the worklist.  */
      block = worklist[--sp];
      vn_context_bb = block;

      /* Initially, the set of available values in BLOCK is that of
	 its immediate dominator.  */
      dom = get_immediate_dominator (CDI_DOMINATORS, block);
      if (dom)
	{
	  bitmap_set_copy (AVAIL_OUT (block), AVAIL_OUT (dom));
	  BB_LIVE_VOP_ON_EXIT (block) = BB_LIVE_VOP_ON_EXIT (dom);
	}

      /* Generate values for PHI nodes.  */
      for (gphi_iterator gsi = gsi_start_phis (block); !gsi_end_p (gsi);
	   gsi_next (&gsi))
	{
	  tree result = gimple_phi_result (gsi.phi ());

	  /* We have no need for virtual phis, as they don't represent
	     actual computations.  */
	  if (virtual_operand_p (result))
	    {
	      BB_LIVE_VOP_ON_EXIT (block) = result;
	      continue;
	    }

	  pre_expr e = get_or_alloc_expr_for_name (result);
	  add_to_value (get_expr_value_id (e), e);
	  bitmap_value_insert_into_set (AVAIL_OUT (block), e);
	  bitmap_insert_into_set (PHI_GEN (block), e);
	}

      BB_MAY_NOTRETURN (block) = 0;

      /* Now compute value numbers and populate value sets with all
	 the expressions computed in BLOCK.  */
      for (gimple_stmt_iterator gsi = gsi_start_bb (block); !gsi_end_p (gsi);
	   gsi_next (&gsi))
	{
	  ssa_op_iter iter;
	  tree op;

	  stmt = gsi_stmt (gsi);

	  /* Cache whether the basic-block has any non-visible side-effect
	     or control flow.
	     If this isn't a call or it is the last stmt in the
	     basic-block then the CFG represents things correctly.  */
	  if (is_gimple_call (stmt) && !stmt_ends_bb_p (stmt))
	    {
	      /* Non-looping const functions always return normally.
		 Otherwise the call might not return or have side-effects
		 that forbids hoisting possibly trapping expressions
		 before it.  */
	      int flags = gimple_call_flags (stmt);
	      if (!(flags & ECF_CONST)
		  || (flags & ECF_LOOPING_CONST_OR_PURE))
		BB_MAY_NOTRETURN (block) = 1;
	    }

	  FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF)
	    {
	      pre_expr e = get_or_alloc_expr_for_name (op);

	      add_to_value (get_expr_value_id (e), e);
	      bitmap_insert_into_set (TMP_GEN (block), e);
	      bitmap_value_insert_into_set (AVAIL_OUT (block), e);
	    }

	  if (gimple_vdef (stmt))
	    BB_LIVE_VOP_ON_EXIT (block) = gimple_vdef (stmt);

	  if (gimple_has_side_effects (stmt)
	      || stmt_could_throw_p (cfun, stmt)
	      || is_gimple_debug (stmt))
	    continue;

	  FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
	    {
	      if (ssa_undefined_value_p (op))
		continue;
	      pre_expr e = get_or_alloc_expr_for_name (op);
	      bitmap_value_insert_into_set (EXP_GEN (block), e);
	    }

	  switch (gimple_code (stmt))
	    {
	    case GIMPLE_RETURN:
	      continue;

	    case GIMPLE_CALL:
	      {
		vn_reference_t ref;
		vn_reference_s ref1;
		pre_expr result = NULL;

		/* We can value number only calls to real functions.  */
		if (gimple_call_internal_p (stmt))
		  continue;

		vn_reference_lookup_call (as_a <gcall *> (stmt), &ref, &ref1);
		if (!ref)
		  continue;

		/* If the value of the call is not invalidated in
		   this block until it is computed, add the expression
		   to EXP_GEN.  */
		if (!gimple_vuse (stmt)
		    || gimple_code
		         (SSA_NAME_DEF_STMT (gimple_vuse (stmt))) == GIMPLE_PHI
		    || gimple_bb (SSA_NAME_DEF_STMT
				    (gimple_vuse (stmt))) != block)
		  {
		    result = pre_expr_pool.allocate ();
		    result->kind = REFERENCE;
		    result->id = 0;
		    PRE_EXPR_REFERENCE (result) = ref;

		    get_or_alloc_expression_id (result);
		    add_to_value (get_expr_value_id (result), result);
		    bitmap_value_insert_into_set (EXP_GEN (block), result);
		  }
		continue;
	      }

	    case GIMPLE_ASSIGN:
	      {
		pre_expr result = NULL;
		switch (vn_get_stmt_kind (stmt))
		  {
		  case VN_NARY:
		    {
		      enum tree_code code = gimple_assign_rhs_code (stmt);
		      vn_nary_op_t nary;

		      /* COND_EXPR and VEC_COND_EXPR are awkward in
			 that they contain an embedded complex expression.
			 Don't even try to shove those through PRE.  */
		      if (code == COND_EXPR
			  || code == VEC_COND_EXPR)
			continue;

		      vn_nary_op_lookup_stmt (stmt, &nary);
		      if (!nary || nary->predicated_values)
			continue;

		      /* If the NARY traps and there was a preceding
		         point in the block that might not return avoid
			 adding the nary to EXP_GEN.  */
		      if (BB_MAY_NOTRETURN (block)
			  && vn_nary_may_trap (nary))
			continue;

		      result = pre_expr_pool.allocate ();
		      result->kind = NARY;
		      result->id = 0;
		      PRE_EXPR_NARY (result) = nary;
		      break;
		    }

		  case VN_REFERENCE:
		    {
		      tree rhs1 = gimple_assign_rhs1 (stmt);
		      alias_set_type set = get_alias_set (rhs1);
		      vec<vn_reference_op_s> operands
			= vn_reference_operands_for_lookup (rhs1);
		      vn_reference_t ref;
		      vn_reference_lookup_pieces (gimple_vuse (stmt), set,
						  TREE_TYPE (rhs1),
						  operands, &ref, VN_WALK);
		      if (!ref)
			{
			  operands.release ();
			  continue;
			}

		      /* If the REFERENCE traps and there was a preceding
		         point in the block that might not return avoid
			 adding the reference to EXP_GEN.  */
		      if (BB_MAY_NOTRETURN (block)
			  && vn_reference_may_trap (ref))
			continue;

		      /* If the value of the reference is not invalidated in
			 this block until it is computed, add the expression
			 to EXP_GEN.  */
		      if (gimple_vuse (stmt))
			{
			  gimple *def_stmt;
			  bool ok = true;
			  def_stmt = SSA_NAME_DEF_STMT (gimple_vuse (stmt));
			  while (!gimple_nop_p (def_stmt)
				 && gimple_code (def_stmt) != GIMPLE_PHI
				 && gimple_bb (def_stmt) == block)
			    {
			      if (stmt_may_clobber_ref_p
				    (def_stmt, gimple_assign_rhs1 (stmt)))
				{
				  ok = false;
				  break;
				}
			      def_stmt
				= SSA_NAME_DEF_STMT (gimple_vuse (def_stmt));
			    }
			  if (!ok)
			    {
			      operands.release ();
			      continue;
			    }
			}

		      /* If the load was value-numbered to another
			 load make sure we do not use its expression
			 for insertion if it wouldn't be a valid
			 replacement.  */
		      /* At the momemt we have a testcase
			 for hoist insertion of aligned vs. misaligned
			 variants in gcc.dg/torture/pr65270-1.c thus
			 with just alignment to be considered we can
			 simply replace the expression in the hashtable
			 with the most conservative one.  */
		      vn_reference_op_t ref1 = &ref->operands.last ();
		      while (ref1->opcode != TARGET_MEM_REF
			     && ref1->opcode != MEM_REF
			     && ref1 != &ref->operands[0])
			--ref1;
		      vn_reference_op_t ref2 = &operands.last ();
		      while (ref2->opcode != TARGET_MEM_REF
			     && ref2->opcode != MEM_REF
			     && ref2 != &operands[0])
			--ref2;
		      if ((ref1->opcode == TARGET_MEM_REF
			   || ref1->opcode == MEM_REF)
			  && (TYPE_ALIGN (ref1->type)
			      > TYPE_ALIGN (ref2->type)))
			ref1->type
			  = build_aligned_type (ref1->type,
						TYPE_ALIGN (ref2->type));
		      /* TBAA behavior is an obvious part so make sure
		         that the hashtable one covers this as well
			 by adjusting the ref alias set and its base.  */
		      if (ref->set == set
			  || alias_set_subset_of (set, ref->set))
			;
		      else if (alias_set_subset_of (ref->set, set))
			{
			  ref->set = set;
			  if (ref1->opcode == MEM_REF)
			    ref1->op0
			      = wide_int_to_tree (TREE_TYPE (ref2->op0),
						  wi::to_wide (ref1->op0));
			  else
			    ref1->op2
			      = wide_int_to_tree (TREE_TYPE (ref2->op2),
						  wi::to_wide (ref1->op2));
			}
		      else
			{
			  ref->set = 0;
			  if (ref1->opcode == MEM_REF)
			    ref1->op0
			      = wide_int_to_tree (ptr_type_node,
						  wi::to_wide (ref1->op0));
			  else
			    ref1->op2
			      = wide_int_to_tree (ptr_type_node,
						  wi::to_wide (ref1->op2));
			}
		      operands.release ();

		      result = pre_expr_pool.allocate ();
		      result->kind = REFERENCE;
		      result->id = 0;
		      PRE_EXPR_REFERENCE (result) = ref;
		      break;
		    }

		  default:
		    continue;
		  }

		get_or_alloc_expression_id (result);
		add_to_value (get_expr_value_id (result), result);
		bitmap_value_insert_into_set (EXP_GEN (block), result);
		continue;
	      }
	    default:
	      break;
	    }
	}

      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  print_bitmap_set (dump_file, EXP_GEN (block),
			    "exp_gen", block->index);
	  print_bitmap_set (dump_file, PHI_GEN (block),
			    "phi_gen", block->index);
	  print_bitmap_set (dump_file, TMP_GEN (block),
			    "tmp_gen", block->index);
	  print_bitmap_set (dump_file, AVAIL_OUT (block),
			    "avail_out", block->index);
	}

      /* Put the dominator children of BLOCK on the worklist of blocks
	 to compute available sets for.  */
      for (son = first_dom_son (CDI_DOMINATORS, block);
	   son;
	   son = next_dom_son (CDI_DOMINATORS, son))
	worklist[sp++] = son;
    }
  vn_context_bb = NULL;

  free (worklist);
}


/* Initialize data structures used by PRE.  */

static void
init_pre (void)
{
  basic_block bb;

  next_expression_id = 1;
  expressions.create (0);
  expressions.safe_push (NULL);
  value_expressions.create (get_max_value_id () + 1);
  value_expressions.safe_grow_cleared (get_max_value_id () + 1);
  name_to_id.create (0);

  inserted_exprs = BITMAP_ALLOC (NULL);

  connect_infinite_loops_to_exit ();
  memset (&pre_stats, 0, sizeof (pre_stats));

  alloc_aux_for_blocks (sizeof (struct bb_bitmap_sets));

  calculate_dominance_info (CDI_DOMINATORS);

  bitmap_obstack_initialize (&grand_bitmap_obstack);
  phi_translate_table = new hash_table<expr_pred_trans_d> (5110);
  expression_to_id = new hash_table<pre_expr_d> (num_ssa_names * 3);
  FOR_ALL_BB_FN (bb, cfun)
    {
      EXP_GEN (bb) = bitmap_set_new ();
      PHI_GEN (bb) = bitmap_set_new ();
      TMP_GEN (bb) = bitmap_set_new ();
      AVAIL_OUT (bb) = bitmap_set_new ();
    }
}


/* Deallocate data structures used by PRE.  */

static void
fini_pre ()
{
  value_expressions.release ();
  expressions.release ();
  BITMAP_FREE (inserted_exprs);
  bitmap_obstack_release (&grand_bitmap_obstack);
  bitmap_set_pool.release ();
  pre_expr_pool.release ();
  delete phi_translate_table;
  phi_translate_table = NULL;
  delete expression_to_id;
  expression_to_id = NULL;
  name_to_id.release ();

  free_aux_for_blocks ();
}

namespace {

const pass_data pass_data_pre =
{
  GIMPLE_PASS, /* type */
  "pre", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_TREE_PRE, /* tv_id */
  ( PROP_cfg | PROP_ssa ), /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  TODO_rebuild_alias, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_pre : public gimple_opt_pass
{
public:
  pass_pre (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_pre, ctxt)
  {}

  /* opt_pass methods: */
  virtual bool gate (function *)
    { return flag_tree_pre != 0 || flag_code_hoisting != 0; }
  virtual unsigned int execute (function *);

}; // class pass_pre

/* Valueization hook for RPO VN when we are calling back to it
   at ANTIC compute time.  */

static tree
pre_valueize (tree name)
{
  if (TREE_CODE (name) == SSA_NAME)
    {
      tree tem = VN_INFO (name)->valnum;
      if (tem != VN_TOP && tem != name)
	{
	  if (TREE_CODE (tem) != SSA_NAME
	      || SSA_NAME_IS_DEFAULT_DEF (tem))
	    return tem;
	  /* We create temporary SSA names for representatives that
	     do not have a definition (yet) but are not default defs either
	     assume they are fine to use.  */
	  basic_block def_bb = gimple_bb (SSA_NAME_DEF_STMT (tem));
	  if (! def_bb
	      || dominated_by_p (CDI_DOMINATORS, vn_context_bb, def_bb))
	    return tem;
	  /* ??? Now we could look for a leader.  Ideally we'd somehow
	     expose RPO VN leaders and get rid of AVAIL_OUT as well...  */
	}
    }
  return name;
}

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

  do_partial_partial =
    flag_tree_partial_pre && optimize_function_for_speed_p (fun);

  /* This has to happen before VN runs because
     loop_optimizer_init may create new phis, etc.  */
  loop_optimizer_init (LOOPS_NORMAL);
  split_edges_for_insertion ();
  scev_initialize ();
  calculate_dominance_info (CDI_DOMINATORS);

  run_rpo_vn (VN_WALK);

  init_pre ();

  vn_valueize = pre_valueize;

  /* Insert can get quite slow on an incredibly large number of basic
     blocks due to some quadratic behavior.  Until this behavior is
     fixed, don't run it when he have an incredibly large number of
     bb's.  If we aren't going to run insert, there is no point in
     computing ANTIC, either, even though it's plenty fast nor do
     we require AVAIL.  */
  if (n_basic_blocks_for_fn (fun) < 4000)
    {
      compute_avail ();
      compute_antic ();
      insert ();
    }

  /* Make sure to remove fake edges before committing our inserts.
     This makes sure we don't end up with extra critical edges that
     we would need to split.  */
  remove_fake_exit_edges ();
  gsi_commit_edge_inserts ();

  /* Eliminate folds statements which might (should not...) end up
     not keeping virtual operands up-to-date.  */
  gcc_assert (!need_ssa_update_p (fun));

  statistics_counter_event (fun, "Insertions", pre_stats.insertions);
  statistics_counter_event (fun, "PA inserted", pre_stats.pa_insert);
  statistics_counter_event (fun, "HOIST inserted", pre_stats.hoist_insert);
  statistics_counter_event (fun, "New PHIs", pre_stats.phis);

  todo |= eliminate_with_rpo_vn (inserted_exprs);

  vn_valueize = NULL;

  /* Because we don't follow exactly the standard PRE algorithm, and decide not
     to insert PHI nodes sometimes, and because value numbering of casts isn't
     perfect, we sometimes end up inserting dead code.   This simple DCE-like
     pass removes any insertions we made that weren't actually used.  */
  simple_dce_from_worklist (inserted_exprs);

  fini_pre ();

  scev_finalize ();
  loop_optimizer_finalize ();

  /* TODO: tail_merge_optimize may merge all predecessors of a block, in which
     case we can merge the block with the remaining predecessor of the block.
     It should either:
     - call merge_blocks after each tail merge iteration
     - call merge_blocks after all tail merge iterations
     - mark TODO_cleanup_cfg when necessary
     - share the cfg cleanup with fini_pre.  */
  todo |= tail_merge_optimize (todo);

  free_rpo_vn ();

  /* Tail merging invalidates the virtual SSA web, together with
     cfg-cleanup opportunities exposed by PRE this will wreck the
     SSA updating machinery.  So make sure to run update-ssa
     manually, before eventually scheduling cfg-cleanup as part of
     the todo.  */
  update_ssa (TODO_update_ssa_only_virtuals);

  return todo;
}

} // anon namespace

gimple_opt_pass *
make_pass_pre (gcc::context *ctxt)
{
  return new pass_pre (ctxt);
}
