/* SSA-PRE for trees.
   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
   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 "tm.h"
#include "ggc.h"
#include "tree.h"
#include "basic-block.h"
#include "diagnostic.h"
#include "tree-inline.h"
#include "tree-flow.h"
#include "gimple.h"
#include "tree-dump.h"
#include "timevar.h"
#include "fibheap.h"
#include "hashtab.h"
#include "tree-iterator.h"
#include "real.h"
#include "alloc-pool.h"
#include "obstack.h"
#include "tree-pass.h"
#include "flags.h"
#include "bitmap.h"
#include "langhooks.h"
#include "cfgloop.h"
#include "tree-ssa-sccvn.h"
#include "params.h"
#include "dbgcnt.h"

/* 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.
   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

   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.

   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.

   insert/insert_aux/do_regular_insertion/do_partial_partial_insertion
   performs these steps.

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

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

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

typedef struct pre_expr_d
{
  enum pre_expr_kind kind;
  unsigned int id;
  pre_expr_union u;
} *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

static int
pre_expr_eq (const void *p1, const void *p2)
{
  const struct pre_expr_d *e1 = (const struct pre_expr_d *) p1;
  const struct pre_expr_d *e2 = (const struct pre_expr_d *) p2;

  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:
      abort();
    }
}

static hashval_t
pre_expr_hash (const void *p1)
{
  const struct pre_expr_d *e = (const struct pre_expr_d *) p1;
  switch (e->kind)
    {
    case CONSTANT:
      return vn_hash_constant_with_type (PRE_EXPR_CONSTANT (e));
    case NAME:
      return iterative_hash_hashval_t (SSA_NAME_VERSION (PRE_EXPR_NAME (e)), 0);
    case NARY:
      return PRE_EXPR_NARY (e)->hashcode;
    case REFERENCE:
      return PRE_EXPR_REFERENCE (e)->hashcode;
    default:
      abort ();
    }
}


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

/* Mapping from expression to id number we can use in bitmap sets.  */
DEF_VEC_P (pre_expr);
DEF_VEC_ALLOC_P (pre_expr, heap);
static VEC(pre_expr, heap) *expressions;
static htab_t expression_to_id;

/* Allocate an expression id for EXPR.  */

static inline unsigned int
alloc_expression_id (pre_expr expr)
{
  void **slot;
  /* Make sure we won't overflow. */
  gcc_assert (next_expression_id + 1 > next_expression_id);
  expr->id = next_expression_id++;
  VEC_safe_push (pre_expr, heap, expressions, expr);
  slot = htab_find_slot (expression_to_id, 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)
{
  void **slot;

  slot = htab_find_slot (expression_to_id, 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 VEC_index (pre_expr, expressions, id);
}

/* Free the expression id field in all of our expressions,
   and then destroy the expressions array.  */

static void
clear_expression_ids (void)
{
  VEC_free (pre_expr, heap, expressions);
}

static alloc_pool pre_expr_pool;

/* 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)
{
  pre_expr result = (pre_expr) pool_alloc (pre_expr_pool);
  unsigned int result_id;

  result->kind = NAME;
  result->id = 0;
  PRE_EXPR_NAME (result) = name;
  result_id = lookup_expression_id (result);
  if (result_id != 0)
    {
      pool_free (pre_expr_pool, result);
      result = expression_for_id (result_id);
      return result;
    }
  get_or_alloc_expression_id (result);
  return result;
}

static bool in_fre = false;

/* An unordered bitmap set.  One bitmap tracks values, the other,
   expressions.  */
typedef struct bitmap_set
{
  bitmap expressions;
  bitmap 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.  */
DEF_VEC_P (bitmap_set_t);
DEF_VEC_ALLOC_P (bitmap_set_t, heap);
static VEC(bitmap_set_t, heap) *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;

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

  /* True we have deferred processing this block during ANTIC
     calculation until its successor is processed.  */
  unsigned int deferred : 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 BB_VISITED(BB) ((bb_value_sets_t) ((BB)->aux))->visited
#define BB_DEFERRED(BB) ((bb_value_sets_t) ((BB)->aux))->deferred


/* Basic block list in postorder.  */
static int *postorder;

/* This structure is used to keep track of statistics on what
   optimization PRE was able to perform.  */
static struct
{
  /* The number of RHS computations eliminated by PRE.  */
  int eliminations;

  /* 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 new PHI nodes added by PRE.  */
  int phis;

  /* The number of values found constant.  */
  int constified;

} pre_stats;

static bool do_partial_partial;
static pre_expr bitmap_find_leader (bitmap_set_t, unsigned int, gimple);
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 void bitmap_insert_into_set_1 (bitmap_set_t, pre_expr, bool);
static bitmap_set_t bitmap_set_new (void);
static tree create_expression_by_pieces (basic_block, pre_expr, gimple_seq *,
					 gimple, tree);
static tree find_or_generate_expression (basic_block, pre_expr, gimple_seq *,
					 gimple);
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 alloc_pool bitmap_set_pool;
static bitmap_obstack grand_bitmap_obstack;

/* To avoid adding 300 temporary variables when we only need one, we
   only create one temporary variable, on demand, and build ssa names
   off that.  We do have to change the variable if the types don't
   match the current variable's type.  */
static tree pretemp;
static tree storetemp;
static tree prephitemp;

/* Set of blocks with statements that have had its EH information
   cleaned up.  */
static bitmap need_eh_cleanup;

/* The phi_translate_table caches phi translations for a given
   expression and predecessor.  */

static htab_t phi_translate_table;

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

typedef struct 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;
} *expr_pred_trans_t;
typedef const struct expr_pred_trans_d *const_expr_pred_trans_t;

/* Return the hash value for a phi translation table entry.  */

static hashval_t
expr_pred_trans_hash (const void *p)
{
  const_expr_pred_trans_t const ve = (const_expr_pred_trans_t) p;
  return ve->hashcode;
}

/* Return true if two phi translation table entries are the same.
   P1 and P2 should point to the expr_pred_trans_t's to be compared.*/

static int
expr_pred_trans_eq (const void *p1, const void *p2)
{
  const_expr_pred_trans_t const ve1 = (const_expr_pred_trans_t) p1;
  const_expr_pred_trans_t const ve2 = (const_expr_pred_trans_t) p2;
  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_eq (ve1->e, ve2->e);
}

/* Search in the phi translation table for the translation of
   expression E in basic block PRED.
   Return the translated value, if found, NULL otherwise.  */

static inline pre_expr
phi_trans_lookup (pre_expr e, basic_block pred)
{
  void **slot;
  struct expr_pred_trans_d ept;

  ept.e = e;
  ept.pred = pred;
  ept.hashcode = iterative_hash_hashval_t (pre_expr_hash (e), pred->index);
  slot = htab_find_slot_with_hash (phi_translate_table, &ept, ept.hashcode,
				   NO_INSERT);
  if (!slot)
    return NULL;
  else
    return ((expr_pred_trans_t) *slot)->v;
}


/* Add the tuple mapping from {expression E, basic block PRED} to
   value V, to the phi translation table.  */

static inline void
phi_trans_add (pre_expr e, pre_expr v, basic_block pred)
{
  void **slot;
  expr_pred_trans_t new_pair = XNEW (struct expr_pred_trans_d);
  new_pair->e = e;
  new_pair->pred = pred;
  new_pair->v = v;
  new_pair->hashcode = iterative_hash_hashval_t (pre_expr_hash (e),
						 pred->index);

  slot = htab_find_slot_with_hash (phi_translate_table, new_pair,
				   new_pair->hashcode, INSERT);
  if (*slot)
    free (*slot);
  *slot = (void *) new_pair;
}


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

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

  gcc_assert (get_expr_value_id (e) == v);

  if (v >= VEC_length (bitmap_set_t, value_expressions))
    {
      VEC_safe_grow_cleared (bitmap_set_t, heap, value_expressions,
			     v + 1);
    }

  set = VEC_index (bitmap_set_t, value_expressions, v);
  if (!set)
    {
      set = bitmap_set_new ();
      VEC_replace (bitmap_set_t, value_expressions, v, set);
    }

  bitmap_insert_into_set_1 (set, e, true);
}

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

static bitmap_set_t
bitmap_set_new (void)
{
  bitmap_set_t ret = (bitmap_set_t) pool_alloc (bitmap_set_pool);
  ret->expressions = BITMAP_ALLOC (&grand_bitmap_obstack);
  ret->values = BITMAP_ALLOC (&grand_bitmap_obstack);
  return ret;
}

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

static unsigned int
get_expr_value_id (pre_expr expr)
{
  switch (expr->kind)
    {
    case CONSTANT:
      {
	unsigned int id;
	id = get_constant_value_id (PRE_EXPR_CONSTANT (expr));
	if (id == 0)
	  {
	    id = get_or_alloc_constant_value_id (PRE_EXPR_CONSTANT (expr));
	    add_to_value (id, expr);
	  }
	return id;
      }
    case NAME:
      return VN_INFO (PRE_EXPR_NAME (expr))->value_id;
    case NARY:
      return PRE_EXPR_NARY (expr)->value_id;
    case REFERENCE:
      return PRE_EXPR_REFERENCE (expr)->value_id;
    default:
      gcc_unreachable ();
    }
}

/* Remove an expression EXPR from a bitmapped set.  */

static void
bitmap_remove_from_set (bitmap_set_t set, pre_expr expr)
{
  unsigned int val  = get_expr_value_id (expr);
  if (!value_id_constant_p (val))
    {
      bitmap_clear_bit (set->values, val);
      bitmap_clear_bit (set->expressions, get_expression_id (expr));
    }
}

static void
bitmap_insert_into_set_1 (bitmap_set_t set, pre_expr expr,
			  bool allow_constants)
{
  unsigned int val  = get_expr_value_id (expr);
  if (allow_constants || !value_id_constant_p (val))
    {
      /* We specifically expect this and only this function to be able to
	 insert constants into a set.  */
      bitmap_set_bit (set->values, val);
      bitmap_set_bit (set->expressions, get_or_alloc_expression_id (expr));
    }
}

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

static void
bitmap_insert_into_set (bitmap_set_t set, pre_expr expr)
{
  bitmap_insert_into_set_1 (set, expr, false);
}

/* 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_FREE (set->expressions);
  BITMAP_FREE (set->values);
}


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

static VEC(pre_expr, heap) *
sorted_array_from_bitmap_set (bitmap_set_t set)
{
  unsigned int i, j;
  bitmap_iterator bi, bj;
  VEC(pre_expr, heap) *result = NULL;

  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_set_t exprset = VEC_index (bitmap_set_t, value_expressions, i);
      FOR_EACH_EXPR_ID_IN_SET (exprset, j, bj)
	{
	  if (bitmap_bit_p (set->expressions, j))
	    VEC_safe_push (pre_expr, heap, result, expression_for_id (j));
        }
    }

  return result;
}

/* Perform bitmapped set operation DEST &= ORIG.  */

static void
bitmap_set_and (bitmap_set_t dest, bitmap_set_t orig)
{
  bitmap_iterator bi;
  unsigned int i;

  if (dest != orig)
    {
      bitmap temp = BITMAP_ALLOC (&grand_bitmap_obstack);

      bitmap_and_into (dest->values, orig->values);
      bitmap_copy (temp, dest->expressions);
      EXECUTE_IF_SET_IN_BITMAP (temp, 0, i, bi)
	{
	  pre_expr expr = expression_for_id (i);
	  unsigned int value_id = get_expr_value_id (expr);
	  if (!bitmap_bit_p (dest->values, value_id))
	    bitmap_clear_bit (dest->expressions, i);
	}
      BITMAP_FREE (temp);
    }
}

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

static bitmap_set_t
bitmap_set_subtract (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 the 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;
  bitmap temp = BITMAP_ALLOC (&grand_bitmap_obstack);

  bitmap_copy (temp, a->expressions);
  EXECUTE_IF_SET_IN_BITMAP (temp, 0, i, bi)
    {
      pre_expr expr = expression_for_id (i);
      if (bitmap_set_contains_value (b, get_expr_value_id (expr)))
	bitmap_remove_from_set (a, expr);
    }
  BITMAP_FREE (temp);
}


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

  if (!set || bitmap_empty_p (set->expressions))
    return false;

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

static inline bool
bitmap_set_contains_expr (bitmap_set_t set, const pre_expr expr)
{
  return bitmap_bit_p (set->expressions, get_expression_id (expr));
}

/* Replace an instance of value LOOKFOR with expression EXPR in SET.  */

static void
bitmap_set_replace_value (bitmap_set_t set, unsigned int lookfor,
			  const pre_expr expr)
{
  bitmap_set_t exprset;
  unsigned int i;
  bitmap_iterator bi;

  if (value_id_constant_p (lookfor))
    return;

  if (!bitmap_set_contains_value (set, lookfor))
    return;

  /* 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.  */
  exprset = VEC_index (bitmap_set_t, value_expressions, lookfor);
  FOR_EACH_EXPR_ID_IN_SET (exprset, i, bi)
    {
      if (bitmap_bit_p (set->expressions, i))
	{
	  bitmap_clear_bit (set->expressions, i);
	  bitmap_set_bit (set->expressions, get_expression_id (expr));
	  return;
	}
    }
}

/* 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 (bitmap_set_contains_value (set, val))
    bitmap_set_replace_value (set, val, expr);
  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);

  if (value_id_constant_p (val))
    return;

  if (!bitmap_set_contains_value (set, val))
    bitmap_insert_into_set (set, expr);
}

/* Print out EXPR to outfile.  */

static void
print_pre_expr (FILE *outfile, const pre_expr expr)
{
  switch (expr->kind)
    {
    case CONSTANT:
      print_generic_expr (outfile, PRE_EXPR_CONSTANT (expr), 0);
      break;
    case NAME:
      print_generic_expr (outfile, PRE_EXPR_NAME (expr), 0);
      break;
    case NARY:
      {
	unsigned int i;
	vn_nary_op_t nary = PRE_EXPR_NARY (expr);
	fprintf (outfile, "{%s,", tree_code_name [nary->opcode]);
	for (i = 0; i < nary->length; i++)
	  {
	    print_generic_expr (outfile, nary->op[i], 0);
	    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;
	     VEC_iterate (vn_reference_op_s, ref->operands, i, vro);
	     i++)
	  {
	    if (vro->opcode != SSA_NAME
		&& TREE_CODE_CLASS (vro->opcode) != tcc_declaration)
	      fprintf (outfile, "%s ", tree_code_name [vro->opcode]);
	    if (vro->op0)
	      {
		if (vro->op1)
		  fprintf (outfile, "<");
		print_generic_expr (outfile, vro->op0, 0);
		if (vro->op1)
		  {
		    fprintf (outfile, ",");
		    print_generic_expr (outfile, vro->op1, 0);
		  }
		if (vro->op1)
		  fprintf (outfile, ">");
	      }
	    if (i != VEC_length (vn_reference_op_s, ref->operands) - 1)
	      fprintf (outfile, ",");
	  }
	fprintf (outfile, "}");
      }
      break;
    }
}
void debug_pre_expr (pre_expr);

/* Like print_pre_expr but always prints to stderr.  */
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);

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

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

void
print_value_expressions (FILE *outfile, unsigned int val)
{
  bitmap_set_t set = VEC_index (bitmap_set_t, value_expressions, val);
  if (set)
    {
      char s[10];
      sprintf (s, "%04d", val);
      print_bitmap_set (outfile, set, s, 0);
    }
}


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;
  pre_expr newexpr = (pre_expr) pool_alloc (pre_expr_pool);
  newexpr->kind = CONSTANT;
  PRE_EXPR_CONSTANT (newexpr) = constant;
  result_id = lookup_expression_id (newexpr);
  if (result_id != 0)
    {
      pool_free (pre_expr_pool, newexpr);
      newexpr = expression_for_id (result_id);
      return newexpr;
    }
  value_id = get_or_alloc_constant_value_id (constant);
  get_or_alloc_expression_id (newexpr);
  add_to_value (value_id, newexpr);
  return newexpr;
}

/* Given a value id V, find the actual tree representing the constant
   value if there is one, and return it. Return NULL if we can't find
   a constant.  */

static tree
get_constant_for_value_id (unsigned int v)
{
  if (value_id_constant_p (v))
    {
      unsigned int i;
      bitmap_iterator bi;
      bitmap_set_t exprset = VEC_index (bitmap_set_t, value_expressions, v);

      FOR_EACH_EXPR_ID_IN_SET (exprset, i, bi)
	{
	  pre_expr expr = expression_for_id (i);
	  if (expr->kind == CONSTANT)
	    return PRE_EXPR_CONSTANT (expr);
	}
    }
  return NULL;
}

/* 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);
  else
    {
      /* More complex expressions can result from SCCVN expression
	 simplification that inserts values for them.  As they all
	 do not have VOPs the get handled by the nary ops struct.  */
      vn_nary_op_t result;
      unsigned int result_id;
      vn_nary_op_lookup (t, &result);
      if (result != NULL)
	{
	  pre_expr e = (pre_expr) pool_alloc (pre_expr_pool);
	  e->kind = NARY;
	  PRE_EXPR_NARY (e) = result;
	  result_id = lookup_expression_id (e);
	  if (result_id != 0)
	    {
	      pool_free (pre_expr_pool, e);
	      e = expression_for_id (result_id);
	      return e;
	    }
	  alloc_expression_id (e);
	  return e;
	}
    }
  return NULL;
}

/* Return the folded version of T if T, when folded, is a gimple
   min_invariant.  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);
	switch (TREE_CODE_CLASS (nary->opcode))
	  {
	  case tcc_expression:
	    if (nary->opcode == TRUTH_NOT_EXPR)
	      goto do_unary;
	    if (nary->opcode != TRUTH_AND_EXPR
		&& nary->opcode != TRUTH_OR_EXPR
		&& nary->opcode != TRUTH_XOR_EXPR)
	      return e;
	    /* Fallthrough.  */
	  case tcc_binary:
	  case tcc_comparison:
	    {
	      /* We have to go from trees to pre exprs to value ids to
		 constants.  */
	      tree naryop0 = nary->op[0];
	      tree naryop1 = nary->op[1];
	      tree result;
	      if (!is_gimple_min_invariant (naryop0))
		{
		  pre_expr rep0 = get_or_alloc_expr_for (naryop0);
		  unsigned int vrep0 = get_expr_value_id (rep0);
		  tree const0 = get_constant_for_value_id (vrep0);
		  if (const0)
		    naryop0 = fold_convert (TREE_TYPE (naryop0), const0);
		}
	      if (!is_gimple_min_invariant (naryop1))
		{
		  pre_expr rep1 = get_or_alloc_expr_for (naryop1);
		  unsigned int vrep1 = get_expr_value_id (rep1);
		  tree const1 = get_constant_for_value_id (vrep1);
		  if (const1)
		    naryop1 = fold_convert (TREE_TYPE (naryop1), const1);
		}
	      result = fold_binary (nary->opcode, nary->type,
				    naryop0, naryop1);
	      if (result && is_gimple_min_invariant (result))
		return get_or_alloc_expr_for_constant (result);
	      /* We might have simplified the expression to a
		 SSA_NAME for example from x_1 * 1.  But we cannot
		 insert a PHI for x_1 unconditionally as x_1 might
		 not be available readily.  */
	      return e;
	    }
	  case tcc_reference:
	    if (nary->opcode != REALPART_EXPR
		&& nary->opcode != IMAGPART_EXPR 
		&& nary->opcode != VIEW_CONVERT_EXPR)
	      return e;
	    /* Fallthrough.  */
	  case tcc_unary:
do_unary:
	    {
	      /* We have to go from trees to pre exprs to value ids to
		 constants.  */
	      tree naryop0 = nary->op[0];
	      tree const0, result;
	      if (is_gimple_min_invariant (naryop0))
		const0 = naryop0;
	      else
		{
		  pre_expr rep0 = get_or_alloc_expr_for (naryop0);
		  unsigned int vrep0 = get_expr_value_id (rep0);
		  const0 = get_constant_for_value_id (vrep0);
		}
	      result = NULL;
	      if (const0)
		{
		  tree type1 = TREE_TYPE (nary->op[0]);
		  const0 = fold_convert (type1, const0);
		  result = fold_unary (nary->opcode, nary->type, const0);
		}
	      if (result && is_gimple_min_invariant (result))
		return get_or_alloc_expr_for_constant (result);
	      return e;
	    }
	  default:
	    return e;
	  }
      }
    case REFERENCE:
      {
	vn_reference_t ref = PRE_EXPR_REFERENCE (e);
	VEC (vn_reference_op_s, heap) *operands = ref->operands;
	vn_reference_op_t op;

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

/* Translate the vuses in the VUSES vector backwards through phi nodes
   in PHIBLOCK, so that they have the value they would have in
   BLOCK. */

static VEC(tree, gc) *
translate_vuses_through_block (VEC (tree, gc) *vuses,
			       basic_block phiblock,
			       basic_block block)
{
  tree oldvuse;
  VEC(tree, gc) *result = NULL;
  int i;

  for (i = 0; VEC_iterate (tree, vuses, i, oldvuse); i++)
    {
      gimple phi = SSA_NAME_DEF_STMT (oldvuse);
      if (gimple_code (phi) == GIMPLE_PHI
	  && gimple_bb (phi) == phiblock)
	{
	  edge e = find_edge (block, gimple_bb (phi));
	  if (e)
	    {
	      tree def = PHI_ARG_DEF (phi, e->dest_idx);
	      if (def != oldvuse)
		{
		  if (!result)
		    result = VEC_copy (tree, gc, vuses);
		  VEC_replace (tree, result, i, def);
		}
	    }
	}
    }

  /* We avoid creating a new copy of the vuses unless something
     actually changed, so result can be NULL.  */
  if (result)
    {
      sort_vuses (result);
      return result;
    }
  return vuses;

}

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

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

  result = bitmap_find_leader (set1, val, NULL);
  if (!result && set2)
    result = bitmap_find_leader (set2, val, NULL);
  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:
      {
	vn_reference_op_t vro;

	gcc_assert (PRE_EXPR_REFERENCE (e)->operands);
	vro = VEC_index (vn_reference_op_s,
			 PRE_EXPR_REFERENCE (e)->operands,
			 0);
	/* We don't store type along with COMPONENT_REF because it is
	   always the same as FIELD_DECL's type.  */
	if (!vro->type)
	  {
	    gcc_assert (vro->opcode == COMPONENT_REF);
	    return TREE_TYPE (vro->op0);
	  }
	return vro->type;
      }

    case NARY:
      return PRE_EXPR_NARY (e)->type;
    }
  gcc_unreachable();
}

/* Get a representative SSA_NAME for a given expression.
   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)
{
  tree exprtype;
  tree name;
  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_set_t exprs = VEC_index (bitmap_set_t, value_expressions,
					value_id);
	FOR_EACH_EXPR_ID_IN_SET (exprs, i, bi)
	  {
	    pre_expr rep = expression_for_id (i);
	    if (rep->kind == NAME)
	      return PRE_EXPR_NAME (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, most likely as the result of
     phi translation.  */
  if (dump_file)
    {
      fprintf (dump_file,
	       "Could not find SSA_NAME representative for expression:");
      print_pre_expr (dump_file, e);
      fprintf (dump_file, "\n");
    }

  exprtype = get_expr_type (e);

  /* Build and insert the assignment of the end result to the temporary
     that we will return.  */
  if (!pretemp || exprtype != TREE_TYPE (pretemp))
    {
      pretemp = create_tmp_var (exprtype, "pretmp");
      get_var_ann (pretemp);
    }

  name = make_ssa_name (pretemp, gimple_build_nop ());
  VN_INFO_GET (name)->value_id = value_id;
  if (e->kind == CONSTANT)
    VN_INFO (name)->valnum = PRE_EXPR_CONSTANT (e);
  else
    VN_INFO (name)->valnum = name;

  add_to_value (value_id, get_or_alloc_expr_for_name (name));
  if (dump_file)
    {
      fprintf (dump_file, "Created SSA_NAME representative ");
      print_generic_expr (dump_file, name, 0);
      fprintf (dump_file, " for expression:");
      print_pre_expr (dump_file, e);
      fprintf (dump_file, "\n");
    }

  return name;
}



static pre_expr
phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
	       basic_block pred, basic_block phiblock);

/* 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 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
		 basic_block pred, basic_block phiblock)
{
  switch (expr->kind)
    {
    case NARY:
      {
	unsigned int i;
	bool changed = false;
	vn_nary_op_t nary = PRE_EXPR_NARY (expr);
	struct vn_nary_op_s newnary;
	/* The NARY structure is only guaranteed to have been
	   allocated to the nary->length operands.  */
	memcpy (&newnary, nary, (sizeof (struct vn_nary_op_s)
				 - sizeof (tree) * (4 - 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 (leader, set1, set2, pred, phiblock);
		if (result && result != leader)
		  {
		    tree name = get_representative_for (result);
		    if (!name)
		      return NULL;
		    newnary.op[i] = name;
		  }
		else if (!result)
		  return NULL;

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

	    tree result = vn_nary_op_lookup_pieces (newnary.length,
						    newnary.opcode,
						    newnary.type,
						    newnary.op[0],
						    newnary.op[1],
						    newnary.op[2],
						    newnary.op[3],
						    &nary);
	    unsigned int new_val_id;

	    expr = (pre_expr) pool_alloc (pre_expr_pool);
	    expr->kind = NARY;
	    expr->id = 0;
	    if (result && is_gimple_min_invariant (result))
	      return get_or_alloc_expr_for_constant (result);


	    if (nary)
	      {
		PRE_EXPR_NARY (expr) = nary;
		constant = fully_constant_expression (expr);
		if (constant != expr)
		  return constant;

		new_val_id = nary->value_id;
		get_or_alloc_expression_id (expr);
	      }
	    else
	      {
		new_val_id = get_next_value_id ();
		VEC_safe_grow_cleared (bitmap_set_t, heap,
				       value_expressions,
				       get_max_value_id() + 1);
		nary = vn_nary_op_insert_pieces (newnary.length,
						 newnary.opcode,
						 newnary.type,
						 newnary.op[0],
						 newnary.op[1],
						 newnary.op[2],
						 newnary.op[3],
						 result, new_val_id);
		PRE_EXPR_NARY (expr) = nary;
		constant = fully_constant_expression (expr);
		if (constant != expr)
		  return constant;
		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, heap) *operands = ref->operands;
	VEC (tree, gc) *vuses = ref->vuses;
	VEC (tree, gc) *newvuses = vuses;
	VEC (vn_reference_op_s, heap) *newoperands = NULL;
	bool changed = false;
	unsigned int i;
	vn_reference_op_t operand;
	vn_reference_t newref;

	for (i = 0; VEC_iterate (vn_reference_op_s, operands, i, operand); i++)
	  {
	    pre_expr opresult;
	    pre_expr leader;
	    tree oldop0 = operand->op0;
	    tree oldop1 = operand->op1;
	    tree oldop2 = operand->op2;
	    tree op0 = oldop0;
	    tree op1 = oldop1;
	    tree op2 = oldop2;
	    tree type = operand->type;
	    vn_reference_op_s newop = *operand;

	    if (op0 && TREE_CODE (op0) == SSA_NAME)
	      {
		unsigned int op_val_id = VN_INFO (op0)->value_id;
		leader = find_leader_in_sets (op_val_id, set1, set2);
		opresult = phi_translate (leader, set1, set2, pred, phiblock);
		if (opresult && opresult != leader)
		  {
		    tree name = get_representative_for (opresult);
		    if (!name)
		      break;
		    op0 = name;
		  }
		else if (!opresult)
		  break;
	      }
	    changed |= op0 != oldop0;

	    if (op1 && TREE_CODE (op1) == SSA_NAME)
	      {
		unsigned int op_val_id = VN_INFO (op1)->value_id;
		leader = find_leader_in_sets (op_val_id, set1, set2);
		opresult = phi_translate (leader, set1, set2, pred, phiblock);
		if (opresult && opresult != leader)
		  {
		    tree name = get_representative_for (opresult);
		    if (!name)
		      break;
		    op1 = name;
		  }
		else if (!opresult)
		  break;
	      }
	    changed |= op1 != oldop1;
	    if (op2 && TREE_CODE (op2) == SSA_NAME)
	      {
		unsigned int op_val_id = VN_INFO (op2)->value_id;
		leader = find_leader_in_sets (op_val_id, set1, set2);
		opresult = phi_translate (leader, set1, set2, pred, phiblock);
		if (opresult && opresult != leader)
		  {
		    tree name = get_representative_for (opresult);
		    if (!name)
		      break;
		    op2 = name;
		  }
		else if (!opresult)
		  break;
	      }
	    changed |= op2 != oldop2;

	    if (!newoperands)
	      newoperands = VEC_copy (vn_reference_op_s, heap, operands);
	    /* We may have changed from an SSA_NAME to a constant */
	    if (newop.opcode == SSA_NAME && TREE_CODE (op0) != SSA_NAME)
	      newop.opcode = TREE_CODE (op0);
	    newop.type = type;
	    newop.op0 = op0;
	    newop.op1 = op1;
	    newop.op2 = op2;
	    VEC_replace (vn_reference_op_s, newoperands, i, &newop);
	  }
	if (i != VEC_length (vn_reference_op_s, operands))
	  {
	    if (newoperands)
	      VEC_free (vn_reference_op_s, heap, newoperands);
	    return NULL;
	  }

	newvuses = translate_vuses_through_block (vuses, phiblock, pred);
	changed |= newvuses != vuses;

	if (changed)
	  {
	    unsigned int new_val_id;
	    pre_expr constant;

	    tree result = vn_reference_lookup_pieces (newvuses,
						      newoperands,
						      &newref, true);
	    if (newref)
	      VEC_free (vn_reference_op_s, heap, newoperands);

	    if (result && is_gimple_min_invariant (result))
	      {
	        gcc_assert (!newoperands);
	        return get_or_alloc_expr_for_constant (result);
	      }

	    expr = (pre_expr) pool_alloc (pre_expr_pool);
	    expr->kind = REFERENCE;
	    expr->id = 0;

	    if (newref)
	      {
		PRE_EXPR_REFERENCE (expr) = newref;
		constant = fully_constant_expression (expr);
		if (constant != expr)
		  return constant;

		new_val_id = newref->value_id;
		get_or_alloc_expression_id (expr);
	      }
	    else
	      {
		new_val_id = get_next_value_id ();
		VEC_safe_grow_cleared (bitmap_set_t, heap, value_expressions,
				       get_max_value_id() + 1);
		newref = vn_reference_insert_pieces (newvuses,
						     newoperands,
						     result, new_val_id);
		newoperands = NULL;
		PRE_EXPR_REFERENCE (expr) = newref;
		constant = fully_constant_expression (expr);
		if (constant != expr)
		  return constant;
		get_or_alloc_expression_id (expr);
	      }
	    add_to_value (new_val_id, expr);
	  }
	VEC_free (vn_reference_op_s, heap, newoperands);
	return expr;
      }
      break;

    case NAME:
      {
	gimple phi = NULL;
	edge e;
	gimple def_stmt;
	tree name = PRE_EXPR_NAME (expr);

	def_stmt = SSA_NAME_DEF_STMT (name);
	if (gimple_code (def_stmt) == GIMPLE_PHI
	    && gimple_bb (def_stmt) == phiblock)
	  phi = def_stmt;
	else
	  return expr;

	e = find_edge (pred, gimple_bb (phi));
	if (e)
	  {
	    tree def = PHI_ARG_DEF (phi, e->dest_idx);
	    pre_expr newexpr;

	    if (TREE_CODE (def) == SSA_NAME)
	      def = VN_INFO (def)->valnum;

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

	    if (TREE_CODE (def) == SSA_NAME && ssa_undefined_value_p (def))
	      return NULL;

	    newexpr = get_or_alloc_expr_for_name (def);
	    return newexpr;
	  }
      }
      return expr;

    default:
      gcc_unreachable ();
    }
}

/* Wrapper around phi_translate_1 providing caching functionality.  */

static pre_expr
phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
	       basic_block pred, basic_block phiblock)
{
  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;

  if (expr->kind != NAME)
    {
      phitrans = phi_trans_lookup (expr, pred);
      if (phitrans)
	return phitrans;
    }

  /* Translate.  */
  phitrans = phi_translate_1 (expr, set1, set2, pred, phiblock);

  /* Don't add empty translations to the cache.  Neither add
     translations of NAMEs as those are cheap to translate.  */
  if (phitrans
      && expr->kind != NAME)
    phi_trans_add (expr, phitrans, pred);

  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, basic_block pred,
		   basic_block phiblock)
{
  VEC (pre_expr, heap) *exprs;
  pre_expr expr;
  int i;

  if (gimple_seq_empty_p (phi_nodes (phiblock)))
    {
      bitmap_set_copy (dest, set);
      return;
    }

  exprs = sorted_array_from_bitmap_set (set);
  for (i = 0; VEC_iterate (pre_expr, exprs, i, expr); i++)
    {
      pre_expr translated;
      translated = phi_translate (expr, set, NULL, pred, phiblock);
      if (!translated)
	continue;

      /* We might end up with multiple expressions from SET being
	 translated to the same value.  In this case we do not want
	 to retain the NARY or REFERENCE expression but prefer a NAME
	 which would be the leader.  */
      if (translated->kind == NAME)
	bitmap_value_replace_in_set (dest, translated);
      else
	bitmap_value_insert_into_set (dest, translated);
    }
  VEC_free (pre_expr, heap, exprs);
}

/* Find the leader for a value (i.e., the name representing that
   value) in a given set, and return it.  If STMT is non-NULL it
   makes sure the defining statement for the leader dominates it.
   Return NULL if no leader is found.  */

static pre_expr
bitmap_find_leader (bitmap_set_t set, unsigned int val, gimple stmt)
{
  if (value_id_constant_p (val))
    {
      unsigned int i;
      bitmap_iterator bi;
      bitmap_set_t exprset = VEC_index (bitmap_set_t, value_expressions, val);

      FOR_EACH_EXPR_ID_IN_SET (exprset, 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_set_t exprset = VEC_index (bitmap_set_t, value_expressions, val);

      EXECUTE_IF_AND_IN_BITMAP (exprset->expressions,
				set->expressions, 0, i, bi)
	{
	  pre_expr val = expression_for_id (i);
	  /* At the point where stmt is not null, there should always
	     be an SSA_NAME first in the list of expressions.  */
	  if (stmt)
	    {
	      gimple def_stmt = SSA_NAME_DEF_STMT (PRE_EXPR_NAME (val));
	      if (gimple_code (def_stmt) != GIMPLE_PHI
		  && gimple_bb (def_stmt) == gimple_bb (stmt)
		  && gimple_uid (def_stmt) >= gimple_uid (stmt))
		continue;
	    }
	  return val;
	}
    }
  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)
{
  int i;
  tree vuse;
  VEC (tree, gc) *vuses = PRE_EXPR_REFERENCE (expr)->vuses;

  /* Conservatively, a value dies if it's vuses are defined in this
     block, unless they come from phi nodes (which are merge operations,
     rather than stores.  */
  for (i = 0; VEC_iterate (tree, vuses, i, vuse); i++)
    {
      gimple def = SSA_NAME_DEF_STMT (vuse);

      if (gimple_bb (def) != block)
	continue;
      if (gimple_code (def) == GIMPLE_PHI)
	continue;
      return true;
    }
  return false;
}


#define union_contains_value(SET1, SET2, VAL)			\
  (bitmap_set_contains_value ((SET1), (VAL))			\
   || ((SET2) && bitmap_set_contains_value ((SET2), (VAL))))

/* Determine if vn_reference_op_t VRO is legal in SET1 U SET2.
 */
static bool
vro_valid_in_sets (bitmap_set_t set1, bitmap_set_t set2,
		   vn_reference_op_t vro)
{
  if (vro->op0 && TREE_CODE (vro->op0) == SSA_NAME)
    {
      struct pre_expr_d temp;
      temp.kind = NAME;
      temp.id = 0;
      PRE_EXPR_NAME (&temp) = vro->op0;
      temp.id = lookup_expression_id (&temp);
      if (temp.id == 0)
	return false;
      if (!union_contains_value (set1, set2,
				 get_expr_value_id (&temp)))
	return false;
    }
  if (vro->op1 && TREE_CODE (vro->op1) == SSA_NAME)
    {
      struct pre_expr_d temp;
      temp.kind = NAME;
      temp.id = 0;
      PRE_EXPR_NAME (&temp) = vro->op1;
      temp.id = lookup_expression_id (&temp);
      if (temp.id == 0)
	return false;
      if (!union_contains_value (set1, set2,
				 get_expr_value_id (&temp)))
	return false;
    }

  if (vro->op2 && TREE_CODE (vro->op2) == SSA_NAME)
    {
      struct pre_expr_d temp;
      temp.kind = NAME;
      temp.id = 0;
      PRE_EXPR_NAME (&temp) = vro->op2;
      temp.id = lookup_expression_id (&temp);
      if (temp.id == 0)
	return false;
      if (!union_contains_value (set1, set2,
				 get_expr_value_id (&temp)))
	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 vuses are killed in this block.
*/

static bool
valid_in_sets (bitmap_set_t set1, bitmap_set_t set2, pre_expr expr,
	       basic_block block)
{
  switch (expr->kind)
    {
    case NAME:
      return bitmap_set_contains_expr (AVAIL_OUT (block), expr);
    case NARY:
      {
	unsigned int i;
	vn_nary_op_t nary = PRE_EXPR_NARY (expr);
	for (i = 0; i < nary->length; i++)
	  {
	    if (TREE_CODE (nary->op[i]) == SSA_NAME)
	      {
		struct pre_expr_d temp;
		temp.kind = NAME;
		temp.id = 0;
		PRE_EXPR_NAME (&temp) = nary->op[i];
		temp.id = lookup_expression_id (&temp);
		if (temp.id == 0)
		  return false;
		if (!union_contains_value (set1, set2,
					   get_expr_value_id (&temp)))
		  return false;
	      }
	  }
	return true;
      }
      break;
    case REFERENCE:
      {
	vn_reference_t ref = PRE_EXPR_REFERENCE (expr);
	vn_reference_op_t vro;
	unsigned int i;

	for (i = 0; VEC_iterate (vn_reference_op_s, ref->operands, i, vro); i++)
	  {
	    if (!vro_valid_in_sets (set1, set2, vro))
	      return false;
	  }
	return !value_dies_in_block_x (expr, block);
      }
    default:
      gcc_unreachable ();
    }
}

/* Clean the set of expressions 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.  This version is used for partial
   anticipation, which means it is not valid in either ANTIC_IN or
   PA_IN.  */

static void
dependent_clean (bitmap_set_t set1, bitmap_set_t set2, basic_block block)
{
  VEC (pre_expr, heap) *exprs = sorted_array_from_bitmap_set (set1);
  pre_expr expr;
  int i;

  for (i = 0; VEC_iterate (pre_expr, exprs, i, expr); i++)
    {
      if (!valid_in_sets (set1, set2, expr, block))
	bitmap_remove_from_set (set1, expr);
    }
  VEC_free (pre_expr, heap, exprs);
}

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

static void
clean (bitmap_set_t set, basic_block block)
{
  VEC (pre_expr, heap) *exprs = sorted_array_from_bitmap_set (set);
  pre_expr expr;
  int i;

  for (i = 0; VEC_iterate (pre_expr, exprs, i, expr); i++)
    {
      if (!valid_in_sets (set, NULL, expr, block))
	bitmap_remove_from_set (set, expr);
    }
  VEC_free (pre_expr, heap, exprs);
}

static sbitmap has_abnormal_preds;

/* List of blocks that may have changed during ANTIC computation and
   thus need to be iterated over.  */

static sbitmap changed_blocks;

/* Decide whether to defer a block for a later iteration, or PHI
   translate SOURCE to DEST using phis in PHIBLOCK.  Return false if we
   should defer the block, and true if we processed it.  */

static bool
defer_or_phi_translate_block (bitmap_set_t dest, bitmap_set_t source,
			      basic_block block, basic_block phiblock)
{
  if (!BB_VISITED (phiblock))
    {
      SET_BIT (changed_blocks, block->index);
      BB_VISITED (block) = 0;
      BB_DEFERRED (block) = 1;
      return false;
    }
  else
    phi_translate_set (dest, source, block, phiblock);
  return true;
}

/* 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])
*/

static bool
compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge)
{
  bool changed = false;
  bitmap_set_t S, old, ANTIC_OUT;
  bitmap_iterator bi;
  unsigned int bii;
  edge e;
  edge_iterator ei;

  old = ANTIC_OUT = S = NULL;
  BB_VISITED (block) = 1;

  /* 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))
    {
      basic_block succ_bb = single_succ (block);

      /* We trade iterations of the dataflow equations for having to
	 phi translate the maximal set, which is incredibly slow
	 (since the maximal set often has 300+ members, even when you
	 have a small number of blocks).
	 Basically, we defer the computation of ANTIC for this block
	 until we have processed it's successor, which will inevitably
	 have a *much* smaller set of values to phi translate once
	 clean has been run on it.
	 The cost of doing this is that we technically perform more
	 iterations, however, they are lower cost iterations.

	 Timings for PRE on tramp3d-v4:
	 without maximal set fix: 11 seconds
	 with maximal set fix/without deferring: 26 seconds
	 with maximal set fix/with deferring: 11 seconds
     */

      if (!defer_or_phi_translate_block (ANTIC_OUT, ANTIC_IN (succ_bb),
					block, succ_bb))
	{
	  changed = true;
	  goto maybe_dump_sets;
	}
    }
  /* 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
    {
      VEC(basic_block, heap) * worklist;
      size_t i;
      basic_block bprime, first = NULL;

      worklist = VEC_alloc (basic_block, heap, EDGE_COUNT (block->succs));
      FOR_EACH_EDGE (e, ei, block->succs)
	{
	  if (!first
	      && BB_VISITED (e->dest))
	    first = e->dest;
	  else if (BB_VISITED (e->dest))
	    VEC_quick_push (basic_block, worklist, e->dest);
	}

      /* Of multiple successors we have to have visited one already.  */
      if (!first)
	{
	  SET_BIT (changed_blocks, block->index);
	  BB_VISITED (block) = 0;
	  BB_DEFERRED (block) = 1;
	  changed = true;
	  VEC_free (basic_block, heap, worklist);
	  goto maybe_dump_sets;
	}

      if (!gimple_seq_empty_p (phi_nodes (first)))
	phi_translate_set (ANTIC_OUT, ANTIC_IN (first), block, first);
      else
	bitmap_set_copy (ANTIC_OUT, ANTIC_IN (first));

      for (i = 0; VEC_iterate (basic_block, worklist, i, bprime); i++)
	{
	  if (!gimple_seq_empty_p (phi_nodes (bprime)))
	    {
	      bitmap_set_t tmp = bitmap_set_new ();
	      phi_translate_set (tmp, ANTIC_IN (bprime), block, bprime);
	      bitmap_set_and (ANTIC_OUT, tmp);
	      bitmap_set_free (tmp);
	    }
	  else
	    bitmap_set_and (ANTIC_OUT, ANTIC_IN (bprime));
	}
      VEC_free (basic_block, heap, worklist);
    }

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

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

  /* Then union in the ANTIC_OUT - TMP_GEN values,
     to get ANTIC_OUT U EXP_GEN - TMP_GEN */
  FOR_EACH_EXPR_ID_IN_SET (S, bii, bi)
    bitmap_value_insert_into_set (ANTIC_IN (block),
				  expression_for_id (bii));

  clean (ANTIC_IN (block), block);

  /* !old->expressions can happen when we deferred a block.  */
  if (!old->expressions || !bitmap_set_equal (old, ANTIC_IN (block)))
    {
      changed = true;
      SET_BIT (changed_blocks, block->index);
      FOR_EACH_EDGE (e, ei, block->preds)
	SET_BIT (changed_blocks, e->src->index);
    }
  else
    RESET_BIT (changed_blocks, block->index);

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

	  print_bitmap_set (dump_file, ANTIC_IN (block), "ANTIC_IN",
			    block->index);

	  if (S)
	    print_bitmap_set (dump_file, S, "S", block->index);
	}
      else
	{
	  fprintf (dump_file,
		   "Block %d was deferred for a future iteration.\n",
		   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] = dependent_clean(PA_OUT[BLOCK] - TMP_GEN[BLOCK]
				  - ANTIC_IN[BLOCK])

*/
static bool
compute_partial_antic_aux (basic_block block,
			   bool block_has_abnormal_pred_edge)
{
  bool changed = false;
  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))
    {
      basic_block succ = single_succ (block);
      if (!(single_succ_edge (block)->flags & EDGE_DFS_BACK))
	phi_translate_set (PA_OUT, PA_IN (succ), block, succ);
    }
  /* If we have multiple successors, we take the union of all of
     them.  */
  else
    {
      VEC(basic_block, heap) * worklist;
      size_t i;
      basic_block bprime;

      worklist = VEC_alloc (basic_block, heap, EDGE_COUNT (block->succs));
      FOR_EACH_EDGE (e, ei, block->succs)
	{
	  if (e->flags & EDGE_DFS_BACK)
	    continue;
	  VEC_quick_push (basic_block, worklist, e->dest);
	}
      if (VEC_length (basic_block, worklist) > 0)
	{
	  for (i = 0; VEC_iterate (basic_block, worklist, i, bprime); i++)
	    {
	      unsigned int i;
	      bitmap_iterator bi;

	      FOR_EACH_EXPR_ID_IN_SET (ANTIC_IN (bprime), i, bi)
		bitmap_value_insert_into_set (PA_OUT,
					      expression_for_id (i));
	      if (!gimple_seq_empty_p (phi_nodes (bprime)))
		{
		  bitmap_set_t pa_in = bitmap_set_new ();
		  phi_translate_set (pa_in, PA_IN (bprime), block, bprime);
		  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 (bprime), i, bi)
		  bitmap_value_insert_into_set (PA_OUT,
						expression_for_id (i));
	    }
	}
      VEC_free (basic_block, heap, worklist);
    }

  /* PA_IN starts with PA_OUT - TMP_GEN.
     Then we subtract things from ANTIC_IN.  */
  PA_IN (block) = bitmap_set_subtract (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));

  dependent_clean (PA_IN (block), ANTIC_IN (block), block);

  if (!bitmap_set_equal (old_PA_IN, PA_IN (block)))
    {
      changed = true;
      SET_BIT (changed_blocks, block->index);
      FOR_EACH_EDGE (e, ei, block->preds)
	SET_BIT (changed_blocks, e->src->index);
    }
  else
    RESET_BIT (changed_blocks, block->index);

 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);
  return changed;
}

/* Compute ANTIC and partial ANTIC sets.  */

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

  /* 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);
  sbitmap_zero (has_abnormal_preds);

  FOR_EACH_BB (block)
    {
      edge_iterator ei;
      edge e;

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

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

  /* At the exit block we anticipate nothing.  */
  ANTIC_IN (EXIT_BLOCK_PTR) = bitmap_set_new ();
  BB_VISITED (EXIT_BLOCK_PTR) = 1;
  PA_IN (EXIT_BLOCK_PTR) = bitmap_set_new ();

  changed_blocks = sbitmap_alloc (last_basic_block + 1);
  sbitmap_ones (changed_blocks);
  while (changed)
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "Starting iteration %d\n", num_iterations);
      num_iterations++;
      changed = false;
      for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; i++)
	{
	  if (TEST_BIT (changed_blocks, postorder[i]))
	    {
	      basic_block block = BASIC_BLOCK (postorder[i]);
	      changed |= compute_antic_aux (block,
					    TEST_BIT (has_abnormal_preds,
						      block->index));
	    }
	}
#ifdef ENABLE_CHECKING
      /* Theoretically possible, but *highly* unlikely.  */
      gcc_assert (num_iterations < 500);
#endif
    }

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

  if (do_partial_partial)
    {
      sbitmap_ones (changed_blocks);
      mark_dfs_back_edges ();
      num_iterations = 0;
      changed = true;
      while (changed)
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file, "Starting iteration %d\n", num_iterations);
	  num_iterations++;
	  changed = false;
	  for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; i++)
	    {
	      if (TEST_BIT (changed_blocks, postorder[i]))
		{
		  basic_block block = BASIC_BLOCK (postorder[i]);
		  changed
		    |= compute_partial_antic_aux (block,
						  TEST_BIT (has_abnormal_preds,
							    block->index));
		}
	    }
#ifdef ENABLE_CHECKING
	  /* Theoretically possible, but *highly* unlikely.  */
	  gcc_assert (num_iterations < 500);
#endif
	}
      statistics_histogram_event (cfun, "compute_partial_antic iterations",
				  num_iterations);
    }
  sbitmap_free (has_abnormal_preds);
  sbitmap_free (changed_blocks);
}

/* Return true if we can value number the call in STMT.  This is true
   if we have a pure or constant call.  */

static bool
can_value_number_call (gimple stmt)
{
  if (gimple_call_flags (stmt) & (ECF_PURE | ECF_CONST))
    return true;
  return false;
}

/* Return true if OP is an exception handler related operation, such as
   FILTER_EXPR or EXC_PTR_EXPR.  */

static bool
is_exception_related (gimple stmt)
{
  return (is_gimple_assign (stmt)
	  && (gimple_assign_rhs_code (stmt) == FILTER_EXPR
	      || gimple_assign_rhs_code (stmt) == EXC_PTR_EXPR));
}

/* Return true if OP is a tree which we can perform PRE on
   on.  This may not match the operations we can value number, but in
   a perfect world would.  */

static bool
can_PRE_operation (tree op)
{
  return UNARY_CLASS_P (op)
    || BINARY_CLASS_P (op)
    || COMPARISON_CLASS_P (op)
    || TREE_CODE (op) == INDIRECT_REF
    || TREE_CODE (op) == COMPONENT_REF
    || TREE_CODE (op) == VIEW_CONVERT_EXPR
    || TREE_CODE (op) == CALL_EXPR
    || TREE_CODE (op) == ARRAY_REF;
}


/* 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 VEC(gimple,heap) *inserted_exprs;

/* Pool allocated fake store expressions are placed onto this
   worklist, which, after performing dead code elimination, is walked
   to see which expressions need to be put into GC'able memory  */
static VEC(gimple, heap) *need_creation;

/* 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,
				  gimple domstmt)
{
  vn_reference_op_t currop = VEC_index (vn_reference_op_s, ref->operands,
					*operand);
  tree genop;
  ++*operand;
  switch (currop->opcode)
    {
    case CALL_EXPR:
      {
	tree folded, sc = NULL_TREE;
	unsigned int nargs = 0;
	tree fn, *args;
	if (TREE_CODE (currop->op0) == FUNCTION_DECL)
	  fn = currop->op0;
	else
	  {
	    pre_expr op0 = get_or_alloc_expr_for (currop->op0);
	    fn = find_or_generate_expression (block, op0, stmts, domstmt);
	    if (!fn)
	      return NULL_TREE;
	  }
	if (currop->op1)
	  {
	    pre_expr scexpr = get_or_alloc_expr_for (currop->op1);
	    sc = find_or_generate_expression (block, scexpr, stmts, domstmt);
	    if (!sc)
	      return NULL_TREE;
	  }
	args = XNEWVEC (tree, VEC_length (vn_reference_op_s,
					  ref->operands) - 1);
	while (*operand < VEC_length (vn_reference_op_s, ref->operands))
	  {
	    args[nargs] = create_component_ref_by_pieces_1 (block, ref,
							    operand, stmts,
							    domstmt);
	    if (!args[nargs])
	      {
		free (args);
		return NULL_TREE;
	      }
	    nargs++;
	  }
	folded = build_call_array (currop->type,
				   (TREE_CODE (fn) == FUNCTION_DECL
				    ? build_fold_addr_expr (fn) : fn),
				   nargs, args);
	free (args);
	if (sc)
	  CALL_EXPR_STATIC_CHAIN (folded) = sc;
	return folded;
      }
      break;
    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 folded;
	tree genop0 = create_component_ref_by_pieces_1 (block, ref,
							operand,
							stmts, domstmt);
	if (!genop0)
	  return NULL_TREE;
	folded = fold_build1 (currop->opcode, currop->type,
			      genop0);
	return folded;
      }
      break;
    case ALIGN_INDIRECT_REF:
    case MISALIGNED_INDIRECT_REF:
    case INDIRECT_REF:
      {
	tree folded;
	tree genop1 = create_component_ref_by_pieces_1 (block, ref,
							operand,
							stmts, domstmt);
	if (!genop1)
	  return NULL_TREE;
	genop1 = fold_convert (build_pointer_type (currop->type),
			       genop1);

	if (currop->opcode == MISALIGNED_INDIRECT_REF)
	  folded = fold_build2 (currop->opcode, currop->type,
				genop1, currop->op1);
	else
	  folded = fold_build1 (currop->opcode, currop->type,
				genop1);
	return folded;
      }
      break;
    case BIT_FIELD_REF:
      {
	tree folded;
	tree genop0 = create_component_ref_by_pieces_1 (block, ref, operand,
							stmts, domstmt);
	pre_expr op1expr = get_or_alloc_expr_for (currop->op0);
	pre_expr op2expr = get_or_alloc_expr_for (currop->op1);
	tree genop1;
	tree genop2;

	if (!genop0)
	  return NULL_TREE;
	genop1 = find_or_generate_expression (block, op1expr, stmts, domstmt);
	if (!genop1)
	  return NULL_TREE;
	genop2 = find_or_generate_expression (block, op2expr, stmts, domstmt);
	if (!genop2)
	  return NULL_TREE;
	folded = fold_build3 (BIT_FIELD_REF, currop->type, genop0, genop1,
			      genop2);
	return folded;
      }

      /* 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;
	pre_expr op1expr;
	tree genop2 = currop->op1;
	pre_expr op2expr;
	tree genop3;
	genop0 = create_component_ref_by_pieces_1 (block, ref, operand,
						   stmts, domstmt);
	if (!genop0)
	  return NULL_TREE;
	op1expr = get_or_alloc_expr_for (genop1);
	genop1 = find_or_generate_expression (block, op1expr, stmts, domstmt);
	if (!genop1)
	  return NULL_TREE;
	if (genop2)
	  {
	    op2expr = get_or_alloc_expr_for (genop2);
	    genop2 = find_or_generate_expression (block, op2expr, stmts,
						  domstmt);
	    if (!genop2)
	      return NULL_TREE;
	  }

	genop3 = currop->op2;
	return build4 (currop->opcode, currop->type, genop0, genop1,
		       genop2, genop3);
      }
    case COMPONENT_REF:
      {
	tree op0;
	tree op1;
	tree genop2 = currop->op1;
	pre_expr op2expr;
	op0 = create_component_ref_by_pieces_1 (block, ref, operand,
						stmts, domstmt);
	if (!op0)
	  return NULL_TREE;
	/* op1 should be a FIELD_DECL, which are represented by
	   themselves.  */
	op1 = currop->op0;
	if (genop2)
	  {
	    op2expr = get_or_alloc_expr_for (genop2);
	    genop2 = find_or_generate_expression (block, op2expr, stmts,
						  domstmt);
	    if (!genop2)
	      return NULL_TREE;
	  }

	return fold_build3 (COMPONENT_REF, TREE_TYPE (op1), op0, op1,
			    genop2);
      }
      break;
    case SSA_NAME:
      {
	pre_expr op0expr = get_or_alloc_expr_for (currop->op0);
	genop = find_or_generate_expression (block, op0expr, stmts, domstmt);
	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 INDIRECT_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, gimple domstmt)
{
  unsigned int op = 0;
  return create_component_ref_by_pieces_1 (block, ref, &op, stmts, domstmt);
}

/* Find a leader for an expression, or generate one using
   create_expression_by_pieces if it's ANTIC but
   complex.
   BLOCK is the basic_block we are looking for leaders in.
   EXPR is the expression to find a leader or generate for.
   STMTS is the statement list to put the inserted expressions on.
   Returns the SSA_NAME of the LHS of the generated expression or the
   leader.
   DOMSTMT if non-NULL is a statement that should be dominated by
   all uses in the generated expression.  If DOMSTMT is non-NULL this
   routine can fail and return NULL_TREE.  Otherwise it will assert
   on failure.  */

static tree
find_or_generate_expression (basic_block block, pre_expr expr,
			     gimple_seq *stmts, gimple domstmt)
{
  pre_expr leader = bitmap_find_leader (AVAIL_OUT (block),
					get_expr_value_id (expr), domstmt);
  tree genop = NULL;
  if (leader)
    {
      if (leader->kind == NAME)
	genop = PRE_EXPR_NAME (leader);
      else if (leader->kind == CONSTANT)
	genop = PRE_EXPR_CONSTANT (leader);
    }

  /* If it's still NULL, it must be a complex expression, so generate
     it recursively.  Not so for FRE though.  */
  if (genop == NULL
      && !in_fre)
    {
      bitmap_set_t exprset;
      unsigned int lookfor = get_expr_value_id (expr);
      bool handled = false;
      bitmap_iterator bi;
      unsigned int i;

      exprset = VEC_index (bitmap_set_t, value_expressions, lookfor);
      FOR_EACH_EXPR_ID_IN_SET (exprset, i, bi)
	{
	  pre_expr temp = expression_for_id (i);
	  if (temp->kind != NAME)
	    {
	      handled = true;
	      genop = create_expression_by_pieces (block, temp, stmts,
						   domstmt,
						   get_expr_type (expr));
	      break;
	    }
	}
      if (!handled && domstmt)
	return NULL_TREE;

      gcc_assert (handled);
    }
  return genop;
}

#define NECESSARY GF_PLF_1

/* 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).
   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).

   If DOMSTMT is non-NULL then we make sure that all uses in the
   expressions dominate that statement.  In this case the function
   can return NULL_TREE to signal failure.  */

static tree
create_expression_by_pieces (basic_block block, pre_expr expr,
			     gimple_seq *stmts, gimple domstmt, tree type)
{
  tree temp, name;
  tree folded, newexpr;
  gimple_seq forced_stmts;
  unsigned int value_id;
  gimple_stmt_iterator gsi;
  tree exprtype = type ? type : get_expr_type (expr);
  pre_expr nameexpr;
  gimple 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);
      break;
    case CONSTANT:
      folded = PRE_EXPR_CONSTANT (expr);
      break;
    case REFERENCE:
      {
	vn_reference_t ref = PRE_EXPR_REFERENCE (expr);
	folded = create_component_ref_by_pieces (block, ref, stmts, domstmt);
      }
      break;
    case NARY:
      {
	vn_nary_op_t nary = PRE_EXPR_NARY (expr);
	switch (nary->length)
	  {
	  case 2:
	    {
	      pre_expr op1 = get_or_alloc_expr_for (nary->op[0]);
	      pre_expr op2 = get_or_alloc_expr_for (nary->op[1]);
	      tree genop1 = find_or_generate_expression (block, op1,
							 stmts, domstmt);
	      tree genop2 = find_or_generate_expression (block, op2,
							 stmts, domstmt);
	      if (!genop1 || !genop2)
		return NULL_TREE;
	      genop1 = fold_convert (TREE_TYPE (nary->op[0]),
				     genop1);
	      /* Ensure op2 is a sizetype for POINTER_PLUS_EXPR.  It
		 may be a constant with the wrong type.  */
	      if (nary->opcode == POINTER_PLUS_EXPR)
		genop2 = fold_convert (sizetype, genop2);
	      else
		genop2 = fold_convert (TREE_TYPE (nary->op[1]), genop2);
	      
	      folded = fold_build2 (nary->opcode, nary->type,
				    genop1, genop2);
	    }
	    break;
	  case 1:
	    {
	      pre_expr op1 = get_or_alloc_expr_for (nary->op[0]);
	      tree genop1 = find_or_generate_expression (block, op1,
							 stmts, domstmt);
	      if (!genop1)
		return NULL_TREE;
	      genop1 = fold_convert (TREE_TYPE (nary->op[0]), genop1);

	      folded = fold_build1 (nary->opcode, nary->type,
				    genop1);
	    }
	    break;
	  default:
	    return NULL_TREE;
	  }
      }
      break;
    default:
      return NULL_TREE;
    }
  folded = fold_convert (exprtype, folded);
  /* Force the generated expression to be a sequence of GIMPLE
     statements.
     We have to call unshare_expr because force_gimple_operand may
     modify the tree we pass to it.  */
  newexpr = force_gimple_operand (unshare_expr (folded), &forced_stmts,
				  false, NULL);

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

	  VEC_safe_push (gimple, heap, inserted_exprs, stmt);
	  if (TREE_CODE (forcedname) == SSA_NAME)
	    {
	      VN_INFO_GET (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);
	      if (!in_fre)
		bitmap_value_replace_in_set (NEW_SETS (block), nameexpr);
	      bitmap_value_replace_in_set (AVAIL_OUT (block), nameexpr);
	    }
	  mark_symbols_for_renaming (stmt);
	}
      gimple_seq_add_seq (stmts, forced_stmts);
    }

  /* Build and insert the assignment of the end result to the temporary
     that we will return.  */
  if (!pretemp || exprtype != TREE_TYPE (pretemp))
    {
      pretemp = create_tmp_var (exprtype, "pretmp");
      get_var_ann (pretemp);
    }

  temp = pretemp;
  add_referenced_var (temp);

  if (TREE_CODE (exprtype) == COMPLEX_TYPE
      || TREE_CODE (exprtype) == VECTOR_TYPE)
    DECL_GIMPLE_REG_P (temp) = 1;

  newstmt = gimple_build_assign (temp, newexpr);
  name = make_ssa_name (temp, newstmt);
  gimple_assign_set_lhs (newstmt, name);
  gimple_set_plf (newstmt, NECESSARY, false);

  gimple_seq_add_stmt (stmts, newstmt);
  VEC_safe_push (gimple, heap, inserted_exprs, newstmt);

  /* All the symbols in NEWEXPR should be put into SSA form.  */
  mark_symbols_for_renaming (newstmt);

  /* 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.  */
  VN_INFO_GET (name)->valnum = name;
  value_id = get_expr_value_id (expr);
  VN_INFO (name)->value_id = value_id;
  nameexpr = get_or_alloc_expr_for_name (name);
  add_to_value (value_id, nameexpr);
  if (!in_fre)
    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, newstmt, 0, 0);
      fprintf (dump_file, " in predecessor %d\n", block->index);
    }

  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,
			    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;
  gimple phi;

  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", val);
    }

  /* Make sure we aren't creating an induction variable.  */
  if (block->loop_depth > 0 && EDGE_COUNT (block->preds) == 2
      && expr->kind != REFERENCE)
    {
      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)
	{
	  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 sure we are not inserting trapping expressions.  */
  FOR_EACH_EDGE (pred, ei, block->preds)
    {
      bprime = pred->src;
      eprime = avail[bprime->index];
      if (eprime->kind == NARY
	  && vn_nary_may_trap (PRE_EXPR_NARY (eprime)))
	return false;
    }

  /* Make the necessary insertions.  */
  FOR_EACH_EDGE (pred, ei, block->preds)
    {
      gimple_seq stmts = NULL;
      tree builtexpr;
      bprime = pred->src;
      eprime = avail[bprime->index];

      if (eprime->kind != NAME && eprime->kind != CONSTANT)
	{
	  builtexpr = create_expression_by_pieces (bprime,
						   eprime,
						   &stmts, NULL,
						   type);
	  gcc_assert (!(pred->flags & EDGE_ABNORMAL));
	  gsi_insert_seq_on_edge (pred, stmts);
	  avail[bprime->index] = get_or_alloc_expr_for_name (builtexpr);
	  insertions = true;
	}
      else if (eprime->kind == CONSTANT)
	{
	  /* Constants may not have the right type, fold_convert
	     should give us back a constant with the right type.
	  */
	  tree constant = PRE_EXPR_CONSTANT (eprime);
	  if (!useless_type_conversion_p (type, TREE_TYPE (constant)))
	    {
	      tree builtexpr = fold_convert (type, constant);
	      if (!is_gimple_min_invariant (builtexpr)) 
		{
		  tree forcedexpr = force_gimple_operand (builtexpr,
							  &stmts, true,
							  NULL);
		  if (!is_gimple_min_invariant (forcedexpr))
		    {
		      if (forcedexpr != builtexpr)
			{
			  VN_INFO_GET (forcedexpr)->valnum = PRE_EXPR_CONSTANT (eprime);
			  VN_INFO (forcedexpr)->value_id = get_expr_value_id (eprime);
			}
		      if (stmts)
			{
			  gimple_stmt_iterator gsi;
			  gsi = gsi_start (stmts);
			  for (; !gsi_end_p (gsi); gsi_next (&gsi))
			    {
			      gimple stmt = gsi_stmt (gsi);
			      VEC_safe_push (gimple, heap, inserted_exprs, stmt);
			      gimple_set_plf (stmt, NECESSARY, false);
			    }
			  gsi_insert_seq_on_edge (pred, stmts);
			}
		      avail[bprime->index] = get_or_alloc_expr_for_name (forcedexpr);
		    }
		}
	    }
	}
      else if (eprime->kind == NAME)
	{
	  /* We may have to do a conversion because our value
	     numbering can look through types in certain cases, but
	     our IL requires all operands of a phi node have the same
	     type.  */
	  tree name = PRE_EXPR_NAME (eprime);
	  if (!useless_type_conversion_p (type, TREE_TYPE (name)))
	    {
	      tree builtexpr;
	      tree forcedexpr;
	      builtexpr = fold_convert (type, name);
	      forcedexpr = force_gimple_operand (builtexpr,
						 &stmts, true,
						 NULL);

	      if (forcedexpr != name)
		{
		  VN_INFO_GET (forcedexpr)->valnum = VN_INFO (name)->valnum;
		  VN_INFO (forcedexpr)->value_id = VN_INFO (name)->value_id;
		}

	      if (stmts)
		{
		  gimple_stmt_iterator gsi;
		  gsi = gsi_start (stmts);
		  for (; !gsi_end_p (gsi); gsi_next (&gsi))
		    {
		      gimple stmt = gsi_stmt (gsi);
		      VEC_safe_push (gimple, heap, inserted_exprs, stmt);
		      gimple_set_plf (stmt, NECESSARY, false);
		    }
		  gsi_insert_seq_on_edge (pred, stmts);
		}
	      avail[bprime->index] = get_or_alloc_expr_for_name (forcedexpr);
	    }
	}
    }
  /* 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.  */
  if (!prephitemp || TREE_TYPE (prephitemp) != type)
    {
      prephitemp = create_tmp_var (type, "prephitmp");
      get_var_ann (prephitemp);
    }

  temp = prephitemp;
  add_referenced_var (temp);

  if (TREE_CODE (type) == COMPLEX_TYPE
      || TREE_CODE (type) == VECTOR_TYPE)
    DECL_GIMPLE_REG_P (temp) = 1;
  phi = create_phi_node (temp, block);

  gimple_set_plf (phi, NECESSARY, false);
  VN_INFO_GET (gimple_phi_result (phi))->valnum = gimple_phi_result (phi);
  VN_INFO (gimple_phi_result (phi))->value_id = val;
  VEC_safe_push (gimple, heap, inserted_exprs, phi);
  FOR_EACH_EDGE (pred, ei, block->preds)
    {
      pre_expr ae = avail[pred->src->index];
      gcc_assert (get_expr_type (ae) == type
		  || useless_type_conversion_p (type, get_expr_type (ae)));
      if (ae->kind == CONSTANT)
	add_phi_arg (phi, PRE_EXPR_CONSTANT (ae), pred);
      else
	add_phi_arg (phi, PRE_EXPR_NAME (avail[pred->src->index]), pred);
    }

  newphi = get_or_alloc_expr_for_name (gimple_phi_result (phi));
  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 (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Created phi ");
      print_gimple_stmt (dump_file, phi, 0, 0);
      fprintf (dump_file, " in block %d\n", block->index);
    }
  pre_stats.phis++;
  return true;
}



/* Perform insertion of partially redundant 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.
   3. Recursively call ourselves on the dominator children of BLOCK.

   Steps 1, 2a, and 3 are done by insert_aux. 2b, 2c and 2d are done by
   do_regular_insertion and do_partial_insertion.

*/

static bool
do_regular_insertion (basic_block block, basic_block dom)
{
  bool new_stuff = false;
  VEC (pre_expr, heap) *exprs = sorted_array_from_bitmap_set (ANTIC_IN (block));
  pre_expr expr;
  int i;

  for (i = 0; VEC_iterate (pre_expr, exprs, i, expr); i++)
    {
      if (expr->kind != NAME)
	{
	  pre_expr *avail;
	  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;

	  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\n");
	      continue;
	    }

	  avail = XCNEWVEC (pre_expr, last_basic_block);
	  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;
	      eprime = phi_translate (expr, ANTIC_IN (block), NULL,
				      bprime, block);

	      /* 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)
		{
		  cant_insert = true;
		  break;
		}

	      eprime = fully_constant_expression (eprime);
	      vprime = get_expr_value_id (eprime);
	      edoubleprime = bitmap_find_leader (AVAIL_OUT (bprime),
						 vprime, NULL);
	      if (edoubleprime == NULL)
		{
		  avail[bprime->index] = eprime;
		  all_same = false;
		}
	      else
		{
		  avail[bprime->index] = edoubleprime;
		  by_some = true;
		  if (first_s == NULL)
		    first_s = edoubleprime;
		  else if (!pre_expr_eq (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 && dbg_cnt (treepre_insert))
	    {
	      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 && eprime
		   && (edoubleprime->kind == CONSTANT
		       || edoubleprime->kind == NAME)
		   && !value_id_constant_p (val))
	    {
	      unsigned int j;
	      bitmap_iterator bi;
	      bitmap_set_t exprset = VEC_index (bitmap_set_t,
						value_expressions, val);

	      unsigned int new_val = get_expr_value_id (edoubleprime);
	      FOR_EACH_EXPR_ID_IN_SET (exprset, j, bi)
		{
		  pre_expr expr = expression_for_id (j);

		  if (expr->kind == NAME)
		    {
		      vn_ssa_aux_t info = VN_INFO (PRE_EXPR_NAME (expr));
		      /* Just reset the value id and valnum so it is
			 the same as the constant we have discovered.  */
		      if (edoubleprime->kind == CONSTANT)
			{
			  info->valnum = PRE_EXPR_CONSTANT (edoubleprime);
			  pre_stats.constified++;
			}
		      else
			info->valnum = VN_INFO (PRE_EXPR_NAME (edoubleprime))->valnum;
		      info->value_id = new_val;
		    }
		}
	    }
	  free (avail);
	}
    }

  VEC_free (pre_expr, heap, exprs);
  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_partial_partial_insertion (basic_block block, basic_block dom)
{
  bool new_stuff = false;
  VEC (pre_expr, heap) *exprs = sorted_array_from_bitmap_set (PA_IN (block));
  pre_expr expr;
  int i;

  for (i = 0; VEC_iterate (pre_expr, exprs, i, expr); i++)
    {
      if (expr->kind != NAME)
	{
	  pre_expr *avail;
	  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;

	  avail = XCNEWVEC (pre_expr, last_basic_block);
	  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 (expr, ANTIC_IN (block),
				      PA_IN (block),
				      bprime, block);

	      /* 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)
		{
		  cant_insert = true;
		  break;
		}

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

	    }

	  /* 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 && dbg_cnt (treepre_insert))
	    {
	      pre_stats.pa_insert++;
	      if (insert_into_preds_of_block (block, get_expression_id (expr),
					      avail))
		new_stuff = true;
	    }
	  free (avail);
	}
    }

  VEC_free (pre_expr, heap, exprs);
  return new_stuff;
}

static bool
insert_aux (basic_block block)
{
  basic_block son;
  bool new_stuff = false;

  if (block)
    {
      basic_block dom;
      dom = get_immediate_dominator (CDI_DOMINATORS, block);
      if (dom)
	{
	  unsigned i;
	  bitmap_iterator bi;
	  bitmap_set_t 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);
		}
	    }
	  if (!single_pred_p (block))
	    {
	      new_stuff |= do_regular_insertion (block, dom);
	      if (do_partial_partial)
		new_stuff |= do_partial_partial_insertion (block, dom);
	    }
	}
    }
  for (son = first_dom_son (CDI_DOMINATORS, block);
       son;
       son = next_dom_son (CDI_DOMINATORS, son))
    {
      new_stuff |= insert_aux (son);
    }

  return new_stuff;
}

/* Perform insertion of partially redundant values.  */

static void
insert (void)
{
  bool new_stuff = true;
  basic_block bb;
  int num_iterations = 0;

  FOR_ALL_BB (bb)
    NEW_SETS (bb) = bitmap_set_new ();

  while (new_stuff)
    {
      num_iterations++;
      new_stuff = insert_aux (ENTRY_BLOCK_PTR);
    }
  statistics_histogram_event (cfun, "insert iterations", num_iterations);
}


/* Add OP to EXP_GEN (block), and possibly to the maximal set.  */

static void
add_to_exp_gen (basic_block block, tree op)
{
  if (!in_fre)
    {
      pre_expr result;
      if (TREE_CODE (op) == SSA_NAME && ssa_undefined_value_p (op))
	return;
      result = get_or_alloc_expr_for_name (op);
      bitmap_value_insert_into_set (EXP_GEN (block), result);
    }
}

/* Create value ids for PHI in BLOCK.  */

static void
make_values_for_phi (gimple phi, basic_block block)
{
  tree result = gimple_phi_result (phi);

  /* We have no need for virtual phis, as they don't represent
     actual computations.  */
  if (is_gimple_reg (result))
    {
      pre_expr e = get_or_alloc_expr_for_name (result);
      add_to_value (get_expr_value_id (e), e);
      bitmap_insert_into_set (PHI_GEN (block), e);
      bitmap_value_insert_into_set (AVAIL_OUT (block), e);
      if (!in_fre)
	{
	  unsigned i;
	  for (i = 0; i < gimple_phi_num_args (phi); ++i)
	    {
	      tree arg = gimple_phi_arg_def (phi, i);
	      if (TREE_CODE (arg) == SSA_NAME)
		{
		  e = get_or_alloc_expr_for_name (arg);
		  add_to_value (get_expr_value_id (e), e);
		}
	    }
	}
    }
}

/* 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;
  tree param;

  /* For arguments with default definitions, we pretend they are
     defined in the entry block.  */
  for (param = DECL_ARGUMENTS (current_function_decl);
       param;
       param = TREE_CHAIN (param))
    {
      if (gimple_default_def (cfun, param) != NULL)
	{
	  tree def = gimple_default_def (cfun, param);
	  pre_expr e = get_or_alloc_expr_for_name (def);

	  add_to_value (get_expr_value_id (e), e);
	  if (!in_fre)
	    bitmap_insert_into_set (TMP_GEN (ENTRY_BLOCK_PTR), e);
	  bitmap_value_insert_into_set (AVAIL_OUT (ENTRY_BLOCK_PTR), e);
	}
    }

  /* Likewise for the static chain decl. */
  if (cfun->static_chain_decl)
    {
      param = cfun->static_chain_decl;
      if (gimple_default_def (cfun, param) != NULL)
	{
	  tree def = gimple_default_def (cfun, param);
	  pre_expr e = get_or_alloc_expr_for_name (def);

	  add_to_value (get_expr_value_id (e), e);
	  if (!in_fre)
	    bitmap_insert_into_set (TMP_GEN (ENTRY_BLOCK_PTR), e);
	  bitmap_value_insert_into_set (AVAIL_OUT (ENTRY_BLOCK_PTR), e);
	}
    }

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

  /* 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);
       son;
       son = next_dom_son (CDI_DOMINATORS, son))
    worklist[sp++] = son;

  /* Loop until the worklist is empty.  */
  while (sp)
    {
      gimple_stmt_iterator gsi;
      gimple stmt;
      basic_block dom;
      unsigned int stmt_uid = 1;

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

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

      /* Generate values for PHI nodes.  */
      for (gsi = gsi_start_phis (block); !gsi_end_p (gsi); gsi_next (&gsi))
	make_values_for_phi (gsi_stmt (gsi), block);

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

	  stmt = gsi_stmt (gsi);
	  gimple_set_uid (stmt, stmt_uid++);

	  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);
	      if (!in_fre)
		bitmap_insert_into_set (TMP_GEN (block), e);
	      bitmap_value_insert_into_set (AVAIL_OUT (block), e);
	    }

	  if (gimple_has_volatile_ops (stmt)
	      || stmt_could_throw_p (stmt))
	    continue;

	  switch (gimple_code (stmt))
	    {
	    case GIMPLE_RETURN:
	      FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
		add_to_exp_gen (block, op);
	      continue;

	    case GIMPLE_CALL:
	      {
		vn_reference_t ref;
		unsigned int i;
		vn_reference_op_t vro;
		pre_expr result = NULL;
		VEC(vn_reference_op_s, heap) *ops = NULL;

		if (!can_value_number_call (stmt))
		  continue;

		copy_reference_ops_from_call (stmt, &ops);
		vn_reference_lookup_pieces (shared_vuses_from_stmt (stmt),
					    ops, &ref, false);
		VEC_free (vn_reference_op_s, heap, ops);
		if (!ref)
		  continue;

		for (i = 0; VEC_iterate (vn_reference_op_s,
					 ref->operands, i,
					 vro); i++)
		  {
		    if (vro->op0 && TREE_CODE (vro->op0) == SSA_NAME)
		      add_to_exp_gen (block, vro->op0);
		    if (vro->op1 && TREE_CODE (vro->op1) == SSA_NAME)
		      add_to_exp_gen (block, vro->op1);
		    if (vro->op2 && TREE_CODE (vro->op2) == SSA_NAME)
		      add_to_exp_gen (block, vro->op2);
		  }
		result = (pre_expr) pool_alloc (pre_expr_pool);
		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);
		if (!in_fre)
		  bitmap_value_insert_into_set (EXP_GEN (block), result);
		continue;
	      }

	    case GIMPLE_ASSIGN:
	      {
		pre_expr result = NULL;
		switch (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)))
		  {
		  case tcc_unary:
		    if (is_exception_related (stmt))
		      continue;
		  case tcc_binary:
		  case tcc_comparison:
		    {
		      vn_nary_op_t nary;
		      unsigned int i;

		      vn_nary_op_lookup_pieces (gimple_num_ops (stmt) - 1,
						gimple_assign_rhs_code (stmt),
						gimple_expr_type (stmt),
						gimple_assign_rhs1 (stmt),
						gimple_assign_rhs2 (stmt),
						NULL_TREE, NULL_TREE, &nary);

		      if (!nary)
			continue;

		      for (i = 0; i < nary->length; i++)
			if (TREE_CODE (nary->op[i]) == SSA_NAME)
			  add_to_exp_gen (block, nary->op[i]);

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

		  case tcc_declaration:
		  case tcc_reference:
		    {
		      vn_reference_t ref;
		      unsigned int i;
		      vn_reference_op_t vro;

		      vn_reference_lookup (gimple_assign_rhs1 (stmt),
					   shared_vuses_from_stmt (stmt),
					   false, &ref);
		      if (!ref)
			continue;

		      for (i = 0; VEC_iterate (vn_reference_op_s,
					       ref->operands, i,
					       vro); i++)
			{
			  if (vro->op0 && TREE_CODE (vro->op0) == SSA_NAME)
			    add_to_exp_gen (block, vro->op0);
			  if (vro->op1 && TREE_CODE (vro->op1) == SSA_NAME)
			    add_to_exp_gen (block, vro->op1);
			  if (vro->op2 && TREE_CODE (vro->op2) == SSA_NAME)
			    add_to_exp_gen (block, vro->op2);
			}
		      result = (pre_expr) pool_alloc (pre_expr_pool);
		      result->kind = REFERENCE;
		      result->id = 0;
		      PRE_EXPR_REFERENCE (result) = ref;
		      break;
		    }

		  default:
		    /* For any other statement that we don't
		       recognize, simply add all referenced
		       SSA_NAMEs to EXP_GEN.  */
		    FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
		      add_to_exp_gen (block, op);
		    continue;
		  }

		get_or_alloc_expression_id (result);
		add_to_value (get_expr_value_id (result), result);
		if (!in_fre)
		  bitmap_value_insert_into_set (EXP_GEN (block), result);

		continue;
	      }
	    default:
	      break;
	    }
	}

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

  free (worklist);
}

/* Insert the expression for SSA_VN that SCCVN thought would be simpler
   than the available expressions for it.  The insertion point is
   right before the first use in STMT.  Returns the SSA_NAME that should
   be used for replacement.  */

static tree
do_SCCVN_insertion (gimple stmt, tree ssa_vn)
{
  basic_block bb = gimple_bb (stmt);
  gimple_stmt_iterator gsi;
  gimple_seq stmts = NULL;
  tree expr;
  pre_expr e;

  /* First create a value expression from the expression we want
     to insert and associate it with the value handle for SSA_VN.  */
  e = get_or_alloc_expr_for (vn_get_expr_for (ssa_vn));
  if (e == NULL)
    return NULL_TREE;

  /* Then use create_expression_by_pieces to generate a valid
     expression to insert at this point of the IL stream.  */
  expr = create_expression_by_pieces (bb, e, &stmts, stmt, NULL);
  if (expr == NULL_TREE)
    return NULL_TREE;
  gsi = gsi_for_stmt (stmt);
  gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);

  return expr;
}

/* Eliminate fully redundant computations.  */

static unsigned int
eliminate (void)
{
  basic_block b;
  unsigned int todo = 0;

  FOR_EACH_BB (b)
    {
      gimple_stmt_iterator i;

      for (i = gsi_start_bb (b); !gsi_end_p (i); gsi_next (&i))
	{
	  gimple stmt = gsi_stmt (i);

	  /* Lookup the RHS of the expression, see if we have an
	     available computation for it.  If so, replace the RHS with
	     the available computation.  */
	  if (gimple_has_lhs (stmt)
	      && TREE_CODE (gimple_get_lhs (stmt)) == SSA_NAME
	      && !gimple_assign_ssa_name_copy_p (stmt)
	      && (!gimple_assign_single_p (stmt)
		  || !is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
	      && !gimple_has_volatile_ops  (stmt)
	      && !has_zero_uses (gimple_get_lhs (stmt)))
	    {
	      tree lhs = gimple_get_lhs (stmt);
	      tree rhs = NULL_TREE;
	      tree sprime = NULL;
	      pre_expr lhsexpr = get_or_alloc_expr_for_name (lhs);
	      pre_expr sprimeexpr;

	      if (gimple_assign_single_p (stmt))
		rhs = gimple_assign_rhs1 (stmt);

	      sprimeexpr = bitmap_find_leader (AVAIL_OUT (b),
					       get_expr_value_id (lhsexpr),
					       NULL);

	      if (sprimeexpr)
		{
		  if (sprimeexpr->kind == CONSTANT)
		    sprime = PRE_EXPR_CONSTANT (sprimeexpr);
		  else if (sprimeexpr->kind == NAME)
		    sprime = PRE_EXPR_NAME (sprimeexpr);
		  else
		    gcc_unreachable ();
		}

	      /* If there is no existing leader but SCCVN knows this
		 value is constant, use that constant.  */
	      if (!sprime && is_gimple_min_invariant (VN_INFO (lhs)->valnum))
		{
		  sprime = fold_convert (TREE_TYPE (lhs),
					 VN_INFO (lhs)->valnum);

		  if (dump_file && (dump_flags & TDF_DETAILS))
		    {
		      fprintf (dump_file, "Replaced ");
		      print_gimple_expr (dump_file, stmt, 0, 0);
		      fprintf (dump_file, " with ");
		      print_generic_expr (dump_file, sprime, 0);
		      fprintf (dump_file, " in ");
		      print_gimple_stmt (dump_file, stmt, 0, 0);
		    }
		  pre_stats.eliminations++;
		  propagate_tree_value_into_stmt (&i, sprime);
		  stmt = gsi_stmt (i);
		  update_stmt (stmt);
		  continue;
		}

	      /* If there is no existing usable leader but SCCVN thinks
		 it has an expression it wants to use as replacement,
		 insert that.  */
	      if (!sprime || sprime == lhs)
		{
		  tree val = VN_INFO (lhs)->valnum;
		  if (val != VN_TOP
		      && TREE_CODE (val) == SSA_NAME
		      && VN_INFO (val)->needs_insertion
		      && can_PRE_operation (vn_get_expr_for (val)))
		    sprime = do_SCCVN_insertion (stmt, val);
		}
	      if (sprime
		  && sprime != lhs
		  && (rhs == NULL_TREE
		      || TREE_CODE (rhs) != SSA_NAME
		      || may_propagate_copy (rhs, sprime)))
		{
		  gcc_assert (sprime != rhs);

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

		  if (TREE_CODE (sprime) == SSA_NAME)
		    gimple_set_plf (SSA_NAME_DEF_STMT (sprime),
				    NECESSARY, true);
		  /* We need to make sure the new and old types actually match,
		     which may require adding a simple cast, which fold_convert
		     will do for us.  */
		  if ((!rhs || TREE_CODE (rhs) != SSA_NAME)
		      && !useless_type_conversion_p (gimple_expr_type (stmt),
						     TREE_TYPE (sprime)))
		    sprime = fold_convert (gimple_expr_type (stmt), sprime);

		  pre_stats.eliminations++;
		  propagate_tree_value_into_stmt (&i, sprime);
		  stmt = gsi_stmt (i);
		  update_stmt (stmt);

		  /* If we removed EH side effects from the statement, clean
		     its EH information.  */
		  if (maybe_clean_or_replace_eh_stmt (stmt, stmt))
		    {
		      bitmap_set_bit (need_eh_cleanup,
				      gimple_bb (stmt)->index);
		      if (dump_file && (dump_flags & TDF_DETAILS))
			fprintf (dump_file, "  Removed EH side effects.\n");
		    }
		}
	    }
	  /* Visit COND_EXPRs and fold the comparison with the
	     available value-numbers.  */
	  else if (gimple_code (stmt) == GIMPLE_COND)
	    {
	      tree op0 = gimple_cond_lhs (stmt);
	      tree op1 = gimple_cond_rhs (stmt);
	      tree result;

	      if (TREE_CODE (op0) == SSA_NAME)
		op0 = VN_INFO (op0)->valnum;
	      if (TREE_CODE (op1) == SSA_NAME)
		op1 = VN_INFO (op1)->valnum;
	      result = fold_binary (gimple_cond_code (stmt), boolean_type_node,
				    op0, op1);
	      if (result && TREE_CODE (result) == INTEGER_CST)
		{
		  if (integer_zerop (result))
		    gimple_cond_make_false (stmt);
		  else
		    gimple_cond_make_true (stmt);
		  update_stmt (stmt);
		  todo = TODO_cleanup_cfg;
		}
	    }
	}
    }

  return todo;
}

/* Borrow a bit of tree-ssa-dce.c for the moment.
   XXX: In 4.1, we should be able to just run a DCE pass after PRE, though
   this may be a bit faster, and we may want critical edges kept split.  */

/* If OP's defining statement has not already been determined to be necessary,
   mark that statement necessary. Return the stmt, if it is newly
   necessary.  */

static inline gimple
mark_operand_necessary (tree op)
{
  gimple stmt;

  gcc_assert (op);

  if (TREE_CODE (op) != SSA_NAME)
    return NULL;

  stmt = SSA_NAME_DEF_STMT (op);
  gcc_assert (stmt);

  if (gimple_plf (stmt, NECESSARY)
      || gimple_nop_p (stmt))
    return NULL;

  gimple_set_plf (stmt, NECESSARY, true);
  return stmt;
}

/* 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.  */

static void
remove_dead_inserted_code (void)
{
  VEC(gimple,heap) *worklist = NULL;
  int i;
  gimple t;

  worklist = VEC_alloc (gimple, heap, VEC_length (gimple, inserted_exprs));
  for (i = 0; VEC_iterate (gimple, inserted_exprs, i, t); i++)
    {
      if (gimple_plf (t, NECESSARY))
	VEC_quick_push (gimple, worklist, t);
    }
  while (VEC_length (gimple, worklist) > 0)
    {
      t = VEC_pop (gimple, worklist);

      /* PHI nodes are somewhat special in that each PHI alternative has
	 data and control dependencies.  All the statements feeding the
	 PHI node's arguments are always necessary. */
      if (gimple_code (t) == GIMPLE_PHI)
	{
	  unsigned k;

	  VEC_reserve (gimple, heap, worklist, gimple_phi_num_args (t));
	  for (k = 0; k < gimple_phi_num_args (t); k++)
	    {
	      tree arg = PHI_ARG_DEF (t, k);
	      if (TREE_CODE (arg) == SSA_NAME)
		{
		  gimple n = mark_operand_necessary (arg);
		  if (n)
		    VEC_quick_push (gimple, worklist, n);
		}
	    }
	}
      else
	{
	  /* Propagate through the operands.  Examine all the USE, VUSE and
	     VDEF operands in this statement.  Mark all the statements
	     which feed this statement's uses as necessary.  */
	  ssa_op_iter iter;
	  tree use;

	  /* The operands of VDEF expressions are also needed as they
	     represent potential definitions that may reach this
	     statement (VDEF operands allow us to follow def-def
	     links).  */

	  FOR_EACH_SSA_TREE_OPERAND (use, t, iter, SSA_OP_ALL_USES)
	    {
	      gimple n = mark_operand_necessary (use);
	      if (n)
		VEC_safe_push (gimple, heap, worklist, n);
	    }
	}
    }

  for (i = 0; VEC_iterate (gimple, inserted_exprs, i, t); i++)
    {
      if (!gimple_plf (t, NECESSARY))
	{
	  gimple_stmt_iterator gsi;

	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "Removing unnecessary insertion:");
	      print_gimple_stmt (dump_file, t, 0, 0);
	    }

	  gsi = gsi_for_stmt (t);
	  if (gimple_code (t) == GIMPLE_PHI)
	    remove_phi_node (&gsi, true);
	  else
	    gsi_remove (&gsi, true);
	  release_defs (t);
	}
    }
  VEC_free (gimple, heap, worklist);
}

/* Initialize data structures used by PRE.  */

static void
init_pre (bool do_fre)
{
  basic_block bb;

  next_expression_id = 1;
  expressions = NULL;
  VEC_safe_push (pre_expr, heap, expressions, NULL);
  value_expressions = VEC_alloc (bitmap_set_t, heap, get_max_value_id () + 1);
  VEC_safe_grow_cleared (bitmap_set_t, heap, value_expressions,
			 get_max_value_id() + 1);

  in_fre = do_fre;

  inserted_exprs = NULL;
  need_creation = NULL;
  pretemp = NULL_TREE;
  storetemp = NULL_TREE;
  prephitemp = NULL_TREE;

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


  postorder = XNEWVEC (int, n_basic_blocks - NUM_FIXED_BLOCKS);
  post_order_compute (postorder, false, false);

  FOR_ALL_BB (bb)
    bb->aux = XCNEWVEC (struct bb_bitmap_sets, 1);

  calculate_dominance_info (CDI_POST_DOMINATORS);
  calculate_dominance_info (CDI_DOMINATORS);

  bitmap_obstack_initialize (&grand_bitmap_obstack);
  phi_translate_table = htab_create (5110, expr_pred_trans_hash,
				     expr_pred_trans_eq, free);
  expression_to_id = htab_create (num_ssa_names * 3,
				  pre_expr_hash,
				  pre_expr_eq, NULL);
  bitmap_set_pool = create_alloc_pool ("Bitmap sets",
				       sizeof (struct bitmap_set), 30);
  pre_expr_pool = create_alloc_pool ("pre_expr nodes",
				     sizeof (struct pre_expr_d), 30);
  FOR_ALL_BB (bb)
    {
      EXP_GEN (bb) = bitmap_set_new ();
      PHI_GEN (bb) = bitmap_set_new ();
      TMP_GEN (bb) = bitmap_set_new ();
      AVAIL_OUT (bb) = bitmap_set_new ();
    }

  need_eh_cleanup = BITMAP_ALLOC (NULL);
}


/* Deallocate data structures used by PRE.  */

static void
fini_pre (bool do_fre)
{
  basic_block bb;

  free (postorder);
  VEC_free (bitmap_set_t, heap, value_expressions);
  VEC_free (gimple, heap, inserted_exprs);
  VEC_free (gimple, heap, need_creation);
  bitmap_obstack_release (&grand_bitmap_obstack);
  free_alloc_pool (bitmap_set_pool);
  free_alloc_pool (pre_expr_pool);
  htab_delete (phi_translate_table);
  htab_delete (expression_to_id);

  FOR_ALL_BB (bb)
    {
      free (bb->aux);
      bb->aux = NULL;
    }

  free_dominance_info (CDI_POST_DOMINATORS);

  if (!bitmap_empty_p (need_eh_cleanup))
    {
      gimple_purge_all_dead_eh_edges (need_eh_cleanup);
      cleanup_tree_cfg ();
    }

  BITMAP_FREE (need_eh_cleanup);

  if (!do_fre)
    loop_optimizer_finalize ();
}

/* Main entry point to the SSA-PRE pass.  DO_FRE is true if the caller
   only wants to do full redundancy elimination.  */

static unsigned int
execute_pre (bool do_fre ATTRIBUTE_UNUSED)
{
  unsigned int todo = 0;

  do_partial_partial = optimize > 2;

  /* This has to happen before SCCVN runs because
     loop_optimizer_init may create new phis, etc.  */
  if (!do_fre)
    loop_optimizer_init (LOOPS_NORMAL);

  if (!run_scc_vn (do_fre))
    {
      if (!do_fre)
	{
	  remove_dead_inserted_code ();
	  loop_optimizer_finalize ();
	}
      
      return 0;
    }
  init_pre (do_fre);


  /* Collect and value number expressions computed in each basic block.  */
  compute_avail ();

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      basic_block bb;

      FOR_ALL_BB (bb)
	{
	  print_bitmap_set (dump_file, EXP_GEN (bb), "exp_gen", bb->index);
	  print_bitmap_set (dump_file, PHI_GEN (bb), "phi_gen", bb->index);
	  print_bitmap_set (dump_file, TMP_GEN (bb), "tmp_gen", bb->index);
	  print_bitmap_set (dump_file, AVAIL_OUT (bb), "avail_out", bb->index);
	}
    }

  /* 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.  */
  if (!do_fre && n_basic_blocks < 4000)
    {
      compute_antic ();
      insert ();
    }

  /* Remove all the redundant expressions.  */
  todo |= eliminate ();

  statistics_counter_event (cfun, "Insertions", pre_stats.insertions);
  statistics_counter_event (cfun, "PA inserted", pre_stats.pa_insert);
  statistics_counter_event (cfun, "New PHIs", pre_stats.phis);
  statistics_counter_event (cfun, "Eliminated", pre_stats.eliminations);
  statistics_counter_event (cfun, "Constified", pre_stats.constified);

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

  clear_expression_ids ();
  free_scc_vn ();
  if (!do_fre)
    remove_dead_inserted_code ();

  fini_pre (do_fre);

  return todo;
}

/* Gate and execute functions for PRE.  */

static unsigned int
do_pre (void)
{
  return TODO_rebuild_alias | execute_pre (false);
}

static bool
gate_pre (void)
{
  /* PRE tends to generate bigger code.  */
  return flag_tree_pre != 0 && optimize_function_for_speed_p (cfun);
}

struct gimple_opt_pass pass_pre =
{
 {
  GIMPLE_PASS,
  "pre",				/* name */
  gate_pre,				/* gate */
  do_pre,				/* execute */
  NULL,					/* sub */
  NULL,					/* next */
  0,					/* static_pass_number */
  TV_TREE_PRE,				/* tv_id */
  PROP_no_crit_edges | PROP_cfg
    | PROP_ssa | PROP_alias,		/* properties_required */
  0,					/* properties_provided */
  0,					/* properties_destroyed */
  0,					/* todo_flags_start */
  TODO_update_ssa_only_virtuals | TODO_dump_func | TODO_ggc_collect
  | TODO_verify_ssa /* todo_flags_finish */
 }
};


/* Gate and execute functions for FRE.  */

static unsigned int
execute_fre (void)
{
  return execute_pre (true);
}

static bool
gate_fre (void)
{
  return flag_tree_fre != 0;
}

struct gimple_opt_pass pass_fre =
{
 {
  GIMPLE_PASS,
  "fre",				/* name */
  gate_fre,				/* gate */
  execute_fre,				/* execute */
  NULL,					/* sub */
  NULL,					/* next */
  0,					/* static_pass_number */
  TV_TREE_FRE,				/* tv_id */
  PROP_cfg | PROP_ssa | PROP_alias,	/* properties_required */
  0,					/* properties_provided */
  0,					/* properties_destroyed */
  0,					/* todo_flags_start */
  TODO_dump_func | TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */
 }
};
