/* SSA Dominator optimizations for trees
   Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
   Contributed by Diego Novillo <dnovillo@redhat.com>

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 2, 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 COPYING.  If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "flags.h"
#include "rtl.h"
#include "tm_p.h"
#include "ggc.h"
#include "basic-block.h"
#include "output.h"
#include "errors.h"
#include "expr.h"
#include "function.h"
#include "diagnostic.h"
#include "timevar.h"
#include "tree-dump.h"
#include "tree-flow.h"
#include "domwalk.h"
#include "real.h"
#include "tree-pass.h"
#include "tree-ssa-propagate.h"
#include "langhooks.h"

/* This file implements optimizations on the dominator tree.  */


/* Structure for recording edge equivalences as well as any pending
   edge redirections during the dominator optimizer.

   Computing and storing the edge equivalences instead of creating
   them on-demand can save significant amounts of time, particularly
   for pathological cases involving switch statements.  

   These structures live for a single iteration of the dominator
   optimizer in the edge's AUX field.  At the end of an iteration we
   free each of these structures and update the AUX field to point
   to any requested redirection target (the code for updating the
   CFG and SSA graph for edge redirection expects redirection edge
   targets to be in the AUX field for each edge.  */

struct edge_info
{
  /* If this edge creates a simple equivalence, the LHS and RHS of
     the equivalence will be stored here.  */
  tree lhs;
  tree rhs;

  /* Traversing an edge may also indicate one or more particular conditions
     are true or false.  The number of recorded conditions can vary, but
     can be determined by the condition's code.  So we have an array
     and its maximum index rather than use a varray.  */
  tree *cond_equivalences;
  unsigned int max_cond_equivalences;

  /* If we can thread this edge this field records the new target.  */
  edge redirection_target;
};


/* Hash table with expressions made available during the renaming process.
   When an assignment of the form X_i = EXPR is found, the statement is
   stored in this table.  If the same expression EXPR is later found on the
   RHS of another statement, it is replaced with X_i (thus performing
   global redundancy elimination).  Similarly as we pass through conditionals
   we record the conditional itself as having either a true or false value
   in this table.  */
static htab_t avail_exprs;

/* Stack of available expressions in AVAIL_EXPRs.  Each block pushes any
   expressions it enters into the hash table along with a marker entry
   (null).  When we finish processing the block, we pop off entries and
   remove the expressions from the global hash table until we hit the
   marker.  */
static VEC(tree_on_heap) *avail_exprs_stack;

/* Stack of trees used to restore the global currdefs to its original
   state after completing optimization of a block and its dominator children.

   An SSA_NAME indicates that the current definition of the underlying
   variable should be set to the given SSA_NAME.

   A _DECL node indicates that the underlying variable has no current
   definition.

   A NULL node is used to mark the last node associated with the
   current block.  */
static VEC(tree_on_heap) *block_defs_stack;

/* Stack of statements we need to rescan during finalization for newly
   exposed variables.

   Statement rescanning must occur after the current block's available
   expressions are removed from AVAIL_EXPRS.  Else we may change the
   hash code for an expression and be unable to find/remove it from
   AVAIL_EXPRS.  */
static VEC(tree_on_heap) *stmts_to_rescan;

/* Structure for entries in the expression hash table.

   This requires more memory for the hash table entries, but allows us
   to avoid creating silly tree nodes and annotations for conditionals,
   eliminates 2 global hash tables and two block local varrays.
   
   It also allows us to reduce the number of hash table lookups we
   have to perform in lookup_avail_expr and finally it allows us to
   significantly reduce the number of calls into the hashing routine
   itself.  */

struct expr_hash_elt
{
  /* The value (lhs) of this expression.  */
  tree lhs;

  /* The expression (rhs) we want to record.  */
  tree rhs;

  /* The annotation if this element corresponds to a statement.  */
  stmt_ann_t ann;

  /* The hash value for RHS/ann.  */
  hashval_t hash;
};

/* Stack of dest,src pairs that need to be restored during finalization.

   A NULL entry is used to mark the end of pairs which need to be
   restored during finalization of this block.  */
static VEC(tree_on_heap) *const_and_copies_stack;

/* Bitmap of SSA_NAMEs known to have a nonzero value, even if we do not
   know their exact value.  */
static bitmap nonzero_vars;

/* Stack of SSA_NAMEs which need their NONZERO_VARS property cleared
   when the current block is finalized. 

   A NULL entry is used to mark the end of names needing their 
   entry in NONZERO_VARS cleared during finalization of this block.  */
static VEC(tree_on_heap) *nonzero_vars_stack;

/* Track whether or not we have changed the control flow graph.  */
static bool cfg_altered;

/* Bitmap of blocks that have had EH statements cleaned.  We should
   remove their dead edges eventually.  */
static bitmap need_eh_cleanup;

/* Statistics for dominator optimizations.  */
struct opt_stats_d
{
  long num_stmts;
  long num_exprs_considered;
  long num_re;
};

static struct opt_stats_d opt_stats;

/* Value range propagation record.  Each time we encounter a conditional
   of the form SSA_NAME COND CONST we create a new vrp_element to record
   how the condition affects the possible values SSA_NAME may have.

   Each record contains the condition tested (COND), and the range of
   values the variable may legitimately have if COND is true.  Note the
   range of values may be a smaller range than COND specifies if we have
   recorded other ranges for this variable.  Each record also contains the
   block in which the range was recorded for invalidation purposes.

   Note that the current known range is computed lazily.  This allows us
   to avoid the overhead of computing ranges which are never queried.

   When we encounter a conditional, we look for records which constrain
   the SSA_NAME used in the condition.  In some cases those records allow
   us to determine the condition's result at compile time.  In other cases
   they may allow us to simplify the condition.

   We also use value ranges to do things like transform signed div/mod
   operations into unsigned div/mod or to simplify ABS_EXPRs. 

   Simple experiments have shown these optimizations to not be all that
   useful on switch statements (much to my surprise).  So switch statement
   optimizations are not performed.

   Note carefully we do not propagate information through each statement
   in the block.  i.e., if we know variable X has a value defined of
   [0, 25] and we encounter Y = X + 1, we do not track a value range
   for Y (which would be [1, 26] if we cared).  Similarly we do not
   constrain values as we encounter narrowing typecasts, etc.  */

struct vrp_element
{
  /* The highest and lowest values the variable in COND may contain when
     COND is true.  Note this may not necessarily be the same values
     tested by COND if the same variable was used in earlier conditionals. 

     Note this is computed lazily and thus can be NULL indicating that
     the values have not been computed yet.  */
  tree low;
  tree high;

  /* The actual conditional we recorded.  This is needed since we compute
     ranges lazily.  */
  tree cond;

  /* The basic block where this record was created.  We use this to determine
     when to remove records.  */
  basic_block bb;
};

/* A hash table holding value range records (VRP_ELEMENTs) for a given
   SSA_NAME.  We used to use a varray indexed by SSA_NAME_VERSION, but
   that gets awful wasteful, particularly since the density objects
   with useful information is very low.  */
static htab_t vrp_data;

/* An entry in the VRP_DATA hash table.  We record the variable and a
   varray of VRP_ELEMENT records associated with that variable.  */
struct vrp_hash_elt
{
  tree var;
  varray_type records;
};

/* Array of variables which have their values constrained by operations
   in this basic block.  We use this during finalization to know
   which variables need their VRP data updated.  */

/* Stack of SSA_NAMEs which had their values constrained by operations
   in this basic block.  During finalization of this block we use this
   list to determine which variables need their VRP data updated.

   A NULL entry marks the end of the SSA_NAMEs associated with this block.  */
static VEC(tree_on_heap) *vrp_variables_stack;

struct eq_expr_value
{
  tree src;
  tree dst;
};

/* Local functions.  */
static void optimize_stmt (struct dom_walk_data *, 
			   basic_block bb,
			   block_stmt_iterator);
static tree lookup_avail_expr (tree, bool);
static hashval_t vrp_hash (const void *);
static int vrp_eq (const void *, const void *);
static hashval_t avail_expr_hash (const void *);
static hashval_t real_avail_expr_hash (const void *);
static int avail_expr_eq (const void *, const void *);
static void htab_statistics (FILE *, htab_t);
static void record_cond (tree, tree);
static void record_const_or_copy (tree, tree);
static void record_equality (tree, tree);
static tree update_rhs_and_lookup_avail_expr (tree, tree, bool);
static tree simplify_rhs_and_lookup_avail_expr (struct dom_walk_data *,
						tree, int);
static tree simplify_cond_and_lookup_avail_expr (tree, stmt_ann_t, int);
static tree simplify_switch_and_lookup_avail_expr (tree, int);
static tree find_equivalent_equality_comparison (tree);
static void record_range (tree, basic_block);
static bool extract_range_from_cond (tree, tree *, tree *, int *);
static void record_equivalences_from_phis (basic_block);
static void record_equivalences_from_incoming_edge (basic_block);
static bool eliminate_redundant_computations (struct dom_walk_data *,
					      tree, stmt_ann_t);
static void record_equivalences_from_stmt (tree, int, stmt_ann_t);
static void thread_across_edge (struct dom_walk_data *, edge);
static void dom_opt_finalize_block (struct dom_walk_data *, basic_block);
static void dom_opt_initialize_block (struct dom_walk_data *, basic_block);
static void propagate_to_outgoing_edges (struct dom_walk_data *, basic_block);
static void remove_local_expressions_from_table (void);
static void restore_vars_to_original_value (void);
static void restore_currdefs_to_original_value (void);
static void register_definitions_for_stmt (tree);
static edge single_incoming_edge_ignoring_loop_edges (basic_block);
static void restore_nonzero_vars_to_original_value (void);
static inline bool unsafe_associative_fp_binop (tree);

/* Local version of fold that doesn't introduce cruft.  */

static tree
local_fold (tree t)
{
  t = fold (t);

  /* Strip away useless type conversions.  Both the NON_LVALUE_EXPR that
     may have been added by fold, and "useless" type conversions that might
     now be apparent due to propagation.  */
  STRIP_USELESS_TYPE_CONVERSION (t);

  return t;
}

/* Allocate an EDGE_INFO for edge E and attach it to E.
   Return the new EDGE_INFO structure.  */

static struct edge_info *
allocate_edge_info (edge e)
{
  struct edge_info *edge_info;

  edge_info = xcalloc (1, sizeof (struct edge_info));

  e->aux = edge_info;
  return edge_info;
}

/* Free all EDGE_INFO structures associated with edges in the CFG.
   If a particular edge can be threaded, copy the redirection
   target from the EDGE_INFO structure into the edge's AUX field
   as required by code to update the CFG and SSA graph for
   jump threading.  */

static void
free_all_edge_infos (void)
{
  basic_block bb;
  edge_iterator ei;
  edge e;

  FOR_EACH_BB (bb)
    {
      FOR_EACH_EDGE (e, ei, bb->preds)
        {
	 struct edge_info *edge_info = e->aux;

	  if (edge_info)
	    {
	      e->aux = edge_info->redirection_target;
	      if (edge_info->cond_equivalences)
		free (edge_info->cond_equivalences);
	      free (edge_info);
	    }
	}
    }
}

/* Jump threading, redundancy elimination and const/copy propagation. 

   This pass may expose new symbols that need to be renamed into SSA.  For
   every new symbol exposed, its corresponding bit will be set in
   VARS_TO_RENAME.  */

static void
tree_ssa_dominator_optimize (void)
{
  struct dom_walk_data walk_data;
  unsigned int i;

  memset (&opt_stats, 0, sizeof (opt_stats));

  for (i = 0; i < num_referenced_vars; i++)
    var_ann (referenced_var (i))->current_def = NULL;

  /* Create our hash tables.  */
  avail_exprs = htab_create (1024, real_avail_expr_hash, avail_expr_eq, free);
  vrp_data = htab_create (ceil_log2 (num_ssa_names), vrp_hash, vrp_eq, free);
  avail_exprs_stack = VEC_alloc (tree_on_heap, 20);
  block_defs_stack = VEC_alloc (tree_on_heap, 20);
  const_and_copies_stack = VEC_alloc (tree_on_heap, 20);
  nonzero_vars_stack = VEC_alloc (tree_on_heap, 20);
  vrp_variables_stack = VEC_alloc (tree_on_heap, 20);
  stmts_to_rescan = VEC_alloc (tree_on_heap, 20);
  nonzero_vars = BITMAP_ALLOC (NULL);
  need_eh_cleanup = BITMAP_ALLOC (NULL);

  /* Setup callbacks for the generic dominator tree walker.  */
  walk_data.walk_stmts_backward = false;
  walk_data.dom_direction = CDI_DOMINATORS;
  walk_data.initialize_block_local_data = NULL;
  walk_data.before_dom_children_before_stmts = dom_opt_initialize_block;
  walk_data.before_dom_children_walk_stmts = optimize_stmt;
  walk_data.before_dom_children_after_stmts = propagate_to_outgoing_edges;
  walk_data.after_dom_children_before_stmts = NULL;
  walk_data.after_dom_children_walk_stmts = NULL;
  walk_data.after_dom_children_after_stmts = dom_opt_finalize_block;
  /* Right now we only attach a dummy COND_EXPR to the global data pointer.
     When we attach more stuff we'll need to fill this out with a real
     structure.  */
  walk_data.global_data = NULL;
  walk_data.block_local_data_size = 0;

  /* Now initialize the dominator walker.  */
  init_walk_dominator_tree (&walk_data);

  calculate_dominance_info (CDI_DOMINATORS);

  /* If we prove certain blocks are unreachable, then we want to
     repeat the dominator optimization process as PHI nodes may
     have turned into copies which allows better propagation of
     values.  So we repeat until we do not identify any new unreachable
     blocks.  */
  do
    {
      /* Optimize the dominator tree.  */
      cfg_altered = false;

      /* Recursively walk the dominator tree optimizing statements.  */
      walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);

      /* If we exposed any new variables, go ahead and put them into
	 SSA form now, before we handle jump threading.  This simplifies
	 interactions between rewriting of _DECL nodes into SSA form
	 and rewriting SSA_NAME nodes into SSA form after block
	 duplication and CFG manipulation.  */
      if (!bitmap_empty_p (vars_to_rename))
	{
	  rewrite_into_ssa (false);
	  bitmap_clear (vars_to_rename);
	}

      free_all_edge_infos ();

      /* Thread jumps, creating duplicate blocks as needed.  */
      cfg_altered = thread_through_all_blocks ();

      /* Removal of statements may make some EH edges dead.  Purge
	 such edges from the CFG as needed.  */
      if (!bitmap_empty_p (need_eh_cleanup))
	{
	  cfg_altered |= tree_purge_all_dead_eh_edges (need_eh_cleanup);
	  bitmap_zero (need_eh_cleanup);
	}

      free_dominance_info (CDI_DOMINATORS);
      cfg_altered = cleanup_tree_cfg ();
      calculate_dominance_info (CDI_DOMINATORS);

      rewrite_ssa_into_ssa ();

      /* Reinitialize the various tables.  */
      bitmap_clear (nonzero_vars);
      htab_empty (avail_exprs);
      htab_empty (vrp_data);

      for (i = 0; i < num_referenced_vars; i++)
	var_ann (referenced_var (i))->current_def = NULL;

      /* Finally, remove everything except invariants in SSA_NAME_VALUE.

	 This must be done before we iterate as we might have a
	 reference to an SSA_NAME which was removed by the call to
	 rewrite_ssa_into_ssa.

	 Long term we will be able to let everything in SSA_NAME_VALUE
	 persist.  However, for now, we know this is the safe thing to do.  */
      for (i = 0; i < num_ssa_names; i++)
	{
	  tree name = ssa_name (i);
	  tree value;

	  if (!name)
	    continue;

	  value = SSA_NAME_VALUE (name);
	  if (value && !is_gimple_min_invariant (value))
	    SSA_NAME_VALUE (name) = NULL;
	}
    }
  while (optimize > 1 && cfg_altered);

  /* Debugging dumps.  */
  if (dump_file && (dump_flags & TDF_STATS))
    dump_dominator_optimization_stats (dump_file);

  /* We emptied the hash table earlier, now delete it completely.  */
  htab_delete (avail_exprs);
  htab_delete (vrp_data);

  /* It is not necessary to clear CURRDEFS, REDIRECTION_EDGES, VRP_DATA,
     CONST_AND_COPIES, and NONZERO_VARS as they all get cleared at the bottom
     of the do-while loop above.  */

  /* And finalize the dominator walker.  */
  fini_walk_dominator_tree (&walk_data);

  /* Free nonzero_vars.  */
  BITMAP_FREE (nonzero_vars);
  BITMAP_FREE (need_eh_cleanup);
  
  VEC_free (tree_on_heap, block_defs_stack);
  VEC_free (tree_on_heap, avail_exprs_stack);
  VEC_free (tree_on_heap, const_and_copies_stack);
  VEC_free (tree_on_heap, nonzero_vars_stack);
  VEC_free (tree_on_heap, vrp_variables_stack);
  VEC_free (tree_on_heap, stmts_to_rescan);
}

static bool
gate_dominator (void)
{
  return flag_tree_dom != 0;
}

struct tree_opt_pass pass_dominator = 
{
  "dom",				/* name */
  gate_dominator,			/* gate */
  tree_ssa_dominator_optimize,		/* execute */
  NULL,					/* sub */
  NULL,					/* next */
  0,					/* static_pass_number */
  TV_TREE_SSA_DOMINATOR_OPTS,		/* tv_id */
  PROP_cfg | PROP_ssa | PROP_alias,	/* properties_required */
  0,					/* properties_provided */
  0,					/* properties_destroyed */
  0,					/* todo_flags_start */
  TODO_dump_func | TODO_rename_vars
    | TODO_verify_ssa,			/* todo_flags_finish */
  0					/* letter */
};


/* We are exiting BB, see if the target block begins with a conditional
   jump which has a known value when reached via BB.  */

static void
thread_across_edge (struct dom_walk_data *walk_data, edge e)
{
  block_stmt_iterator bsi;
  tree stmt = NULL;
  tree phi;

  /* Each PHI creates a temporary equivalence, record them.  */
  for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi))
    {
      tree src = PHI_ARG_DEF_FROM_EDGE (phi, e);
      tree dst = PHI_RESULT (phi);

      /* If the desired argument is not the same as this PHI's result 
	 and it is set by a PHI in this block, then we can not thread
	 through this block.  */
      if (src != dst
	  && TREE_CODE (src) == SSA_NAME
	  && TREE_CODE (SSA_NAME_DEF_STMT (src)) == PHI_NODE
	  && bb_for_stmt (SSA_NAME_DEF_STMT (src)) == e->dest)
	return;

      record_const_or_copy (dst, src);
      register_new_def (dst, &block_defs_stack);
    }

  for (bsi = bsi_start (e->dest); ! bsi_end_p (bsi); bsi_next (&bsi))
    {
      tree lhs, cached_lhs;

      stmt = bsi_stmt (bsi);

      /* Ignore empty statements and labels.  */
      if (IS_EMPTY_STMT (stmt) || TREE_CODE (stmt) == LABEL_EXPR)
	continue;

      /* If this is not a MODIFY_EXPR which sets an SSA_NAME to a new
	 value, then stop our search here.  Ideally when we stop a
	 search we stop on a COND_EXPR or SWITCH_EXPR.  */
      if (TREE_CODE (stmt) != MODIFY_EXPR
	  || TREE_CODE (TREE_OPERAND (stmt, 0)) != SSA_NAME)
	break;

      /* At this point we have a statement which assigns an RHS to an
	 SSA_VAR on the LHS.  We want to prove that the RHS is already
	 available and that its value is held in the current definition
	 of the LHS -- meaning that this assignment is a NOP when
	 reached via edge E.  */
      if (TREE_CODE (TREE_OPERAND (stmt, 1)) == SSA_NAME)
	cached_lhs = TREE_OPERAND (stmt, 1);
      else
	cached_lhs = lookup_avail_expr (stmt, false);

      lhs = TREE_OPERAND (stmt, 0);

      /* This can happen if we thread around to the start of a loop.  */
      if (lhs == cached_lhs)
	break;

      /* If we did not find RHS in the hash table, then try again after
	 temporarily const/copy propagating the operands.  */
      if (!cached_lhs)
	{
	  /* Copy the operands.  */
	  stmt_ann_t ann = stmt_ann (stmt);
	  use_optype uses = USE_OPS (ann);
	  vuse_optype vuses = VUSE_OPS (ann);
	  tree *uses_copy = xmalloc (NUM_USES (uses) * sizeof (tree));
	  tree *vuses_copy = xmalloc (NUM_VUSES (vuses) * sizeof (tree));
	  unsigned int i;

	  /* Make a copy of the uses into USES_COPY, then cprop into
	     the use operands.  */
	  for (i = 0; i < NUM_USES (uses); i++)
	    {
	      tree tmp = NULL;

	      uses_copy[i] = USE_OP (uses, i);
	      if (TREE_CODE (USE_OP (uses, i)) == SSA_NAME)
		tmp = SSA_NAME_VALUE (USE_OP (uses, i));
	      if (tmp && TREE_CODE (tmp) != VALUE_HANDLE)
		SET_USE_OP (uses, i, tmp);
	    }

	  /* Similarly for virtual uses.  */
	  for (i = 0; i < NUM_VUSES (vuses); i++)
	    {
	      tree tmp = NULL;

	      vuses_copy[i] = VUSE_OP (vuses, i);
	      if (TREE_CODE (VUSE_OP (vuses, i)) == SSA_NAME)
		tmp = SSA_NAME_VALUE (VUSE_OP (vuses, i));
	      if (tmp && TREE_CODE (tmp) != VALUE_HANDLE)
		SET_VUSE_OP (vuses, i, tmp);
	    }

	  /* Try to lookup the new expression.  */
	  cached_lhs = lookup_avail_expr (stmt, false);

	  /* Restore the statement's original uses/defs.  */
	  for (i = 0; i < NUM_USES (uses); i++)
	    SET_USE_OP (uses, i, uses_copy[i]);

	  for (i = 0; i < NUM_VUSES (vuses); i++)
	    SET_VUSE_OP (vuses, i, vuses_copy[i]);

	  free (uses_copy);
	  free (vuses_copy);

	  /* If we still did not find the expression in the hash table,
	     then we can not ignore this statement.  */
	  if (! cached_lhs)
	    break;
	}

      /* If the expression in the hash table was not assigned to an
	 SSA_NAME, then we can not ignore this statement.  */
      if (TREE_CODE (cached_lhs) != SSA_NAME)
	break;

      /* If we have different underlying variables, then we can not
	 ignore this statement.  */
      if (SSA_NAME_VAR (cached_lhs) != SSA_NAME_VAR (lhs))
	break;

      /* If CACHED_LHS does not represent the current value of the underlying
	 variable in CACHED_LHS/LHS, then we can not ignore this statement.  */
      if (var_ann (SSA_NAME_VAR (lhs))->current_def != cached_lhs)
	break;

      /* If we got here, then we can ignore this statement and continue
	 walking through the statements in the block looking for a threadable
	 COND_EXPR.

	 We want to record an equivalence lhs = cache_lhs so that if
	 the result of this statement is used later we can copy propagate
	 suitably.  */
      record_const_or_copy (lhs, cached_lhs);
      register_new_def (lhs, &block_defs_stack);
    }

  /* If we stopped at a COND_EXPR or SWITCH_EXPR, then see if we know which
     arm will be taken.  */
  if (stmt
      && (TREE_CODE (stmt) == COND_EXPR
	  || TREE_CODE (stmt) == SWITCH_EXPR))
    {
      tree cond, cached_lhs;

      /* Now temporarily cprop the operands and try to find the resulting
	 expression in the hash tables.  */
      if (TREE_CODE (stmt) == COND_EXPR)
	cond = COND_EXPR_COND (stmt);
      else
	cond = SWITCH_COND (stmt);

      if (COMPARISON_CLASS_P (cond))
	{
	  tree dummy_cond, op0, op1;
	  enum tree_code cond_code;

	  op0 = TREE_OPERAND (cond, 0);
	  op1 = TREE_OPERAND (cond, 1);
	  cond_code = TREE_CODE (cond);

	  /* Get the current value of both operands.  */
	  if (TREE_CODE (op0) == SSA_NAME)
	    {
	      tree tmp = SSA_NAME_VALUE (op0);
	      if (tmp && TREE_CODE (tmp) != VALUE_HANDLE)
		op0 = tmp;
	    }

	  if (TREE_CODE (op1) == SSA_NAME)
	    {
	      tree tmp = SSA_NAME_VALUE (op1);
	      if (tmp && TREE_CODE (tmp) != VALUE_HANDLE)
		op1 = tmp;
	    }

	  /* Stuff the operator and operands into our dummy conditional
	     expression, creating the dummy conditional if necessary.  */
	  dummy_cond = walk_data->global_data;
	  if (! dummy_cond)
	    {
	      dummy_cond = build (cond_code, boolean_type_node, op0, op1);
	      dummy_cond = build (COND_EXPR, void_type_node,
				  dummy_cond, NULL, NULL);
	      walk_data->global_data = dummy_cond;
	    }
	  else
	    {
	      TREE_SET_CODE (COND_EXPR_COND (dummy_cond), cond_code);
	      TREE_OPERAND (COND_EXPR_COND (dummy_cond), 0) = op0;
	      TREE_OPERAND (COND_EXPR_COND (dummy_cond), 1) = op1;
	    }

	  /* If the conditional folds to an invariant, then we are done,
	     otherwise look it up in the hash tables.  */
	  cached_lhs = local_fold (COND_EXPR_COND (dummy_cond));
	  if (! is_gimple_min_invariant (cached_lhs))
	    {
	      cached_lhs = lookup_avail_expr (dummy_cond, false);
	      if (!cached_lhs || ! is_gimple_min_invariant (cached_lhs))
		cached_lhs = simplify_cond_and_lookup_avail_expr (dummy_cond,
								  NULL,
								  false);
	    }
	}
      /* We can have conditionals which just test the state of a
	 variable rather than use a relational operator.  These are
	 simpler to handle.  */
      else if (TREE_CODE (cond) == SSA_NAME)
	{
	  cached_lhs = cond;
	  cached_lhs = SSA_NAME_VALUE (cached_lhs);
	  if (cached_lhs && ! is_gimple_min_invariant (cached_lhs))
	    cached_lhs = 0;
	}
      else
	cached_lhs = lookup_avail_expr (stmt, false);

      if (cached_lhs)
	{
	  edge taken_edge = find_taken_edge (e->dest, cached_lhs);
	  basic_block dest = (taken_edge ? taken_edge->dest : NULL);

	  if (dest == e->dest)
	    return;

	  /* If we have a known destination for the conditional, then
	     we can perform this optimization, which saves at least one
	     conditional jump each time it applies since we get to
	     bypass the conditional at our original destination.  */
	  if (dest)
	    {
	      struct edge_info *edge_info;

	      update_bb_profile_for_threading (e->dest, EDGE_FREQUENCY (e),
					       e->count, taken_edge);
	      if (e->aux)
		edge_info = e->aux;
	      else
		edge_info = allocate_edge_info (e);
	      edge_info->redirection_target = taken_edge;
	      bb_ann (e->dest)->incoming_edge_threaded = true;
	    }
	}
    }
}


/* Initialize local stacks for this optimizer and record equivalences
   upon entry to BB.  Equivalences can come from the edge traversed to
   reach BB or they may come from PHI nodes at the start of BB.  */

static void
dom_opt_initialize_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
			  basic_block bb)
{
  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "\n\nOptimizing block #%d\n\n", bb->index);

  /* Push a marker on the stacks of local information so that we know how
     far to unwind when we finalize this block.  */
  VEC_safe_push (tree_on_heap, avail_exprs_stack, NULL_TREE);
  VEC_safe_push (tree_on_heap, block_defs_stack, NULL_TREE);
  VEC_safe_push (tree_on_heap, const_and_copies_stack, NULL_TREE);
  VEC_safe_push (tree_on_heap, nonzero_vars_stack, NULL_TREE);
  VEC_safe_push (tree_on_heap, vrp_variables_stack, NULL_TREE);

  record_equivalences_from_incoming_edge (bb);

  /* PHI nodes can create equivalences too.  */
  record_equivalences_from_phis (bb);
}

/* Given an expression EXPR (a relational expression or a statement), 
   initialize the hash table element pointed by by ELEMENT.  */

static void
initialize_hash_element (tree expr, tree lhs, struct expr_hash_elt *element)
{
  /* Hash table elements may be based on conditional expressions or statements.

     For the former case, we have no annotation and we want to hash the
     conditional expression.  In the latter case we have an annotation and
     we want to record the expression the statement evaluates.  */
  if (COMPARISON_CLASS_P (expr) || TREE_CODE (expr) == TRUTH_NOT_EXPR)
    {
      element->ann = NULL;
      element->rhs = expr;
    }
  else if (TREE_CODE (expr) == COND_EXPR)
    {
      element->ann = stmt_ann (expr);
      element->rhs = COND_EXPR_COND (expr);
    }
  else if (TREE_CODE (expr) == SWITCH_EXPR)
    {
      element->ann = stmt_ann (expr);
      element->rhs = SWITCH_COND (expr);
    }
  else if (TREE_CODE (expr) == RETURN_EXPR && TREE_OPERAND (expr, 0))
    {
      element->ann = stmt_ann (expr);
      element->rhs = TREE_OPERAND (TREE_OPERAND (expr, 0), 1);
    }
  else
    {
      element->ann = stmt_ann (expr);
      element->rhs = TREE_OPERAND (expr, 1);
    }

  element->lhs = lhs;
  element->hash = avail_expr_hash (element);
}

/* Remove all the expressions in LOCALS from TABLE, stopping when there are
   LIMIT entries left in LOCALs.  */

static void
remove_local_expressions_from_table (void)
{
  /* Remove all the expressions made available in this block.  */
  while (VEC_length (tree_on_heap, avail_exprs_stack) > 0)
    {
      struct expr_hash_elt element;
      tree expr = VEC_pop (tree_on_heap, avail_exprs_stack);

      if (expr == NULL_TREE)
	break;

      initialize_hash_element (expr, NULL, &element);
      htab_remove_elt_with_hash (avail_exprs, &element, element.hash);
    }
}

/* Use the SSA_NAMES in LOCALS to restore TABLE to its original
   state, stopping when there are LIMIT entries left in LOCALs.  */

static void
restore_nonzero_vars_to_original_value (void)
{
  while (VEC_length (tree_on_heap, nonzero_vars_stack) > 0)
    {
      tree name = VEC_pop (tree_on_heap, nonzero_vars_stack);

      if (name == NULL)
	break;

      bitmap_clear_bit (nonzero_vars, SSA_NAME_VERSION (name));
    }
}

/* Use the source/dest pairs in CONST_AND_COPIES_STACK to restore
   CONST_AND_COPIES to its original state, stopping when we hit a
   NULL marker.  */

static void
restore_vars_to_original_value (void)
{
  while (VEC_length (tree_on_heap, const_and_copies_stack) > 0)
    {
      tree prev_value, dest;

      dest = VEC_pop (tree_on_heap, const_and_copies_stack);

      if (dest == NULL)
	break;

      prev_value = VEC_pop (tree_on_heap, const_and_copies_stack);
      SSA_NAME_VALUE (dest) =  prev_value;
    }
}

/* Similar to restore_vars_to_original_value, except that it restores 
   CURRDEFS to its original value.  */
static void
restore_currdefs_to_original_value (void)
{
  /* Restore CURRDEFS to its original state.  */
  while (VEC_length (tree_on_heap, block_defs_stack) > 0)
    {
      tree tmp = VEC_pop (tree_on_heap, block_defs_stack);
      tree saved_def, var;

      if (tmp == NULL_TREE)
	break;

      /* If we recorded an SSA_NAME, then make the SSA_NAME the current
	 definition of its underlying variable.  If we recorded anything
	 else, it must have been an _DECL node and its current reaching
	 definition must have been NULL.  */
      if (TREE_CODE (tmp) == SSA_NAME)
	{
	  saved_def = tmp;
	  var = SSA_NAME_VAR (saved_def);
	}
      else
	{
	  saved_def = NULL;
	  var = tmp;
	}
                                                                                
      var_ann (var)->current_def = saved_def;
    }
}

/* We have finished processing the dominator children of BB, perform
   any finalization actions in preparation for leaving this node in
   the dominator tree.  */

static void
dom_opt_finalize_block (struct dom_walk_data *walk_data, basic_block bb)
{
  tree last;

  /* If we are at a leaf node in the dominator tree, see if we can thread
     the edge from BB through its successor.

     Do this before we remove entries from our equivalence tables.  */
  if (EDGE_COUNT (bb->succs) == 1
      && (EDGE_SUCC (bb, 0)->flags & EDGE_ABNORMAL) == 0
      && (get_immediate_dominator (CDI_DOMINATORS, EDGE_SUCC (bb, 0)->dest) != bb
	  || phi_nodes (EDGE_SUCC (bb, 0)->dest)))
	
    {
      thread_across_edge (walk_data, EDGE_SUCC (bb, 0));
    }
  else if ((last = last_stmt (bb))
	   && TREE_CODE (last) == COND_EXPR
	   && (COMPARISON_CLASS_P (COND_EXPR_COND (last))
	       || TREE_CODE (COND_EXPR_COND (last)) == SSA_NAME)
	   && EDGE_COUNT (bb->succs) == 2
	   && (EDGE_SUCC (bb, 0)->flags & EDGE_ABNORMAL) == 0
	   && (EDGE_SUCC (bb, 1)->flags & EDGE_ABNORMAL) == 0)
    {
      edge true_edge, false_edge;

      extract_true_false_edges_from_block (bb, &true_edge, &false_edge);

      /* If the THEN arm is the end of a dominator tree or has PHI nodes,
	 then try to thread through its edge.  */
      if (get_immediate_dominator (CDI_DOMINATORS, true_edge->dest) != bb
	  || phi_nodes (true_edge->dest))
	{
	  struct edge_info *edge_info;
	  unsigned int i;

	  /* Push a marker onto the available expression stack so that we
	     unwind any expressions related to the TRUE arm before processing
	     the false arm below.  */
	  VEC_safe_push (tree_on_heap, avail_exprs_stack, NULL_TREE);
	  VEC_safe_push (tree_on_heap, block_defs_stack, NULL_TREE);
	  VEC_safe_push (tree_on_heap, const_and_copies_stack, NULL_TREE);

	  edge_info = true_edge->aux;

	  /* If we have info associated with this edge, record it into
	     our equivalency tables.  */
	  if (edge_info)
	    {
	      tree *cond_equivalences = edge_info->cond_equivalences;
	      tree lhs = edge_info->lhs;
	      tree rhs = edge_info->rhs;

	      /* If we have a simple NAME = VALUE equivalency record it.
		 Until the jump threading selection code improves, only
		 do this if both the name and value are SSA_NAMEs with
		 the same underlying variable to avoid missing threading
		 opportunities.  */
	      if (lhs
		  && TREE_CODE (COND_EXPR_COND (last)) == SSA_NAME
		  && TREE_CODE (edge_info->rhs) == SSA_NAME
		  && SSA_NAME_VAR (lhs) == SSA_NAME_VAR (rhs))
		record_const_or_copy (lhs, rhs);

	      /* If we have 0 = COND or 1 = COND equivalences, record them
		 into our expression hash tables.  */
	      if (cond_equivalences)
		for (i = 0; i < edge_info->max_cond_equivalences; i += 2)
		  {
		    tree expr = cond_equivalences[i];
		    tree value = cond_equivalences[i + 1];

		    record_cond (expr, value);
		  }
	    }

	  /* Now thread the edge.  */
	  thread_across_edge (walk_data, true_edge);

	  /* And restore the various tables to their state before
	     we threaded this edge.  */
	  remove_local_expressions_from_table ();
	  restore_vars_to_original_value ();
	  restore_currdefs_to_original_value ();
	}

      /* Similarly for the ELSE arm.  */
      if (get_immediate_dominator (CDI_DOMINATORS, false_edge->dest) != bb
	  || phi_nodes (false_edge->dest))
	{
	  struct edge_info *edge_info;
	  unsigned int i;

	  edge_info = false_edge->aux;

	  /* If we have info associated with this edge, record it into
	     our equivalency tables.  */
	  if (edge_info)
	    {
	      tree *cond_equivalences = edge_info->cond_equivalences;
	      tree lhs = edge_info->lhs;
	      tree rhs = edge_info->rhs;

	      /* If we have a simple NAME = VALUE equivalency record it.
		 Until the jump threading selection code improves, only
		 do this if both the name and value are SSA_NAMEs with
		 the same underlying variable to avoid missing threading
		 opportunities.  */
	      if (lhs
		  && TREE_CODE (COND_EXPR_COND (last)) == SSA_NAME)
		record_const_or_copy (lhs, rhs);

	      /* If we have 0 = COND or 1 = COND equivalences, record them
		 into our expression hash tables.  */
	      if (cond_equivalences)
		for (i = 0; i < edge_info->max_cond_equivalences; i += 2)
		  {
		    tree expr = cond_equivalences[i];
		    tree value = cond_equivalences[i + 1];

		    record_cond (expr, value);
		  }
	    }

	  thread_across_edge (walk_data, false_edge);

	  /* No need to remove local expressions from our tables
	     or restore vars to their original value as that will
	     be done immediately below.  */
	}
    }

  remove_local_expressions_from_table ();
  restore_nonzero_vars_to_original_value ();
  restore_vars_to_original_value ();
  restore_currdefs_to_original_value ();

  /* Remove VRP records associated with this basic block.  They are no
     longer valid.

     To be efficient, we note which variables have had their values
     constrained in this block.  So walk over each variable in the
     VRP_VARIABLEs array.  */
  while (VEC_length (tree_on_heap, vrp_variables_stack) > 0)
    {
      tree var = VEC_pop (tree_on_heap, vrp_variables_stack);
      struct vrp_hash_elt vrp_hash_elt, *vrp_hash_elt_p;
      void **slot;

      /* Each variable has a stack of value range records.  We want to
	 invalidate those associated with our basic block.  So we walk
	 the array backwards popping off records associated with our
	 block.  Once we hit a record not associated with our block
	 we are done.  */
      varray_type var_vrp_records;

      if (var == NULL)
	break;

      vrp_hash_elt.var = var;
      vrp_hash_elt.records = NULL;

      slot = htab_find_slot (vrp_data, &vrp_hash_elt, NO_INSERT);

      vrp_hash_elt_p = (struct vrp_hash_elt *) *slot;
      var_vrp_records = vrp_hash_elt_p->records;

      while (VARRAY_ACTIVE_SIZE (var_vrp_records) > 0)
	{
	  struct vrp_element *element
	    = (struct vrp_element *)VARRAY_TOP_GENERIC_PTR (var_vrp_records);

	  if (element->bb != bb)
	    break;
  
	  VARRAY_POP (var_vrp_records);
	}
    }

  /* If we queued any statements to rescan in this block, then
     go ahead and rescan them now.  */
  while (VEC_length (tree_on_heap, stmts_to_rescan) > 0)
    {
      tree stmt = VEC_last (tree_on_heap, stmts_to_rescan);
      basic_block stmt_bb = bb_for_stmt (stmt);

      if (stmt_bb != bb)
	break;

      VEC_pop (tree_on_heap, stmts_to_rescan);
      mark_new_vars_to_rename (stmt, vars_to_rename);
    }
}

/* PHI nodes can create equivalences too.

   Ignoring any alternatives which are the same as the result, if
   all the alternatives are equal, then the PHI node creates an
   equivalence.

   Additionally, if all the PHI alternatives are known to have a nonzero
   value, then the result of this PHI is known to have a nonzero value,
   even if we do not know its exact value.  */

static void
record_equivalences_from_phis (basic_block bb)
{
  tree phi;

  for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
    {
      tree lhs = PHI_RESULT (phi);
      tree rhs = NULL;
      int i;

      for (i = 0; i < PHI_NUM_ARGS (phi); i++)
	{
	  tree t = PHI_ARG_DEF (phi, i);

	  /* Ignore alternatives which are the same as our LHS.  Since
	     LHS is a PHI_RESULT, it is known to be a SSA_NAME, so we
	     can simply compare pointers.  */
	  if (lhs == t)
	    continue;

	  /* If we have not processed an alternative yet, then set
	     RHS to this alternative.  */
	  if (rhs == NULL)
	    rhs = t;
	  /* If we have processed an alternative (stored in RHS), then
	     see if it is equal to this one.  If it isn't, then stop
	     the search.  */
	  else if (! operand_equal_for_phi_arg_p (rhs, t))
	    break;
	}

      /* If we had no interesting alternatives, then all the RHS alternatives
	 must have been the same as LHS.  */
      if (!rhs)
	rhs = lhs;

      /* If we managed to iterate through each PHI alternative without
	 breaking out of the loop, then we have a PHI which may create
	 a useful equivalence.  We do not need to record unwind data for
	 this, since this is a true assignment and not an equivalence
	 inferred from a comparison.  All uses of this ssa name are dominated
	 by this assignment, so unwinding just costs time and space.  */
      if (i == PHI_NUM_ARGS (phi)
	  && may_propagate_copy (lhs, rhs))
	SSA_NAME_VALUE (lhs) = rhs;

      /* Now see if we know anything about the nonzero property for the
	 result of this PHI.  */
      for (i = 0; i < PHI_NUM_ARGS (phi); i++)
	{
	  if (!PHI_ARG_NONZERO (phi, i))
	    break;
	}

      if (i == PHI_NUM_ARGS (phi))
	bitmap_set_bit (nonzero_vars, SSA_NAME_VERSION (PHI_RESULT (phi)));

      register_new_def (lhs, &block_defs_stack);
    }
}

/* Ignoring loop backedges, if BB has precisely one incoming edge then
   return that edge.  Otherwise return NULL.  */
static edge
single_incoming_edge_ignoring_loop_edges (basic_block bb)
{
  edge retval = NULL;
  edge e;
  edge_iterator ei;

  FOR_EACH_EDGE (e, ei, bb->preds)
    {
      /* A loop back edge can be identified by the destination of
	 the edge dominating the source of the edge.  */
      if (dominated_by_p (CDI_DOMINATORS, e->src, e->dest))
	continue;

      /* If we have already seen a non-loop edge, then we must have
	 multiple incoming non-loop edges and thus we return NULL.  */
      if (retval)
	return NULL;

      /* This is the first non-loop incoming edge we have found.  Record
	 it.  */
      retval = e;
    }

  return retval;
}

/* Record any equivalences created by the incoming edge to BB.  If BB
   has more than one incoming edge, then no equivalence is created.  */

static void
record_equivalences_from_incoming_edge (basic_block bb)
{
  edge e;
  basic_block parent;
  struct edge_info *edge_info;

  /* If our parent block ended with a control statement, then we may be
     able to record some equivalences based on which outgoing edge from
     the parent was followed.  */
  parent = get_immediate_dominator (CDI_DOMINATORS, bb);

  e = single_incoming_edge_ignoring_loop_edges (bb);

  /* If we had a single incoming edge from our parent block, then enter
     any data associated with the edge into our tables.  */
  if (e && e->src == parent)
    {
      unsigned int i;

      edge_info = e->aux;

      if (edge_info)
	{
	  tree lhs = edge_info->lhs;
	  tree rhs = edge_info->rhs;
	  tree *cond_equivalences = edge_info->cond_equivalences;

	  if (lhs)
	    record_equality (lhs, rhs);

	  if (cond_equivalences)
	    {
	      bool recorded_range = false;
	      for (i = 0; i < edge_info->max_cond_equivalences; i += 2)
		{
		  tree expr = cond_equivalences[i];
		  tree value = cond_equivalences[i + 1];

		  record_cond (expr, value);

		  /* For the first true equivalence, record range
		     information.  We only do this for the first
		     true equivalence as it should dominate any
		     later true equivalences.  */
		  if (! recorded_range 
		      && COMPARISON_CLASS_P (expr)
		      && value == boolean_true_node
		      && TREE_CONSTANT (TREE_OPERAND (expr, 1)))
		    {
		      record_range (expr, bb);
		      recorded_range = true;
		    }
		}
	    }
	}
    }
}

/* Dump SSA statistics on FILE.  */

void
dump_dominator_optimization_stats (FILE *file)
{
  long n_exprs;

  fprintf (file, "Total number of statements:                   %6ld\n\n",
	   opt_stats.num_stmts);
  fprintf (file, "Exprs considered for dominator optimizations: %6ld\n",
           opt_stats.num_exprs_considered);

  n_exprs = opt_stats.num_exprs_considered;
  if (n_exprs == 0)
    n_exprs = 1;

  fprintf (file, "    Redundant expressions eliminated:         %6ld (%.0f%%)\n",
	   opt_stats.num_re, PERCENT (opt_stats.num_re,
				      n_exprs));

  fprintf (file, "\nHash table statistics:\n");

  fprintf (file, "    avail_exprs: ");
  htab_statistics (file, avail_exprs);
}


/* Dump SSA statistics on stderr.  */

void
debug_dominator_optimization_stats (void)
{
  dump_dominator_optimization_stats (stderr);
}


/* Dump statistics for the hash table HTAB.  */

static void
htab_statistics (FILE *file, htab_t htab)
{
  fprintf (file, "size %ld, %ld elements, %f collision/search ratio\n",
	   (long) htab_size (htab),
	   (long) htab_elements (htab),
	   htab_collisions (htab));
}

/* Record the fact that VAR has a nonzero value, though we may not know
   its exact value.  Note that if VAR is already known to have a nonzero
   value, then we do nothing.  */

static void
record_var_is_nonzero (tree var)
{
  int indx = SSA_NAME_VERSION (var);

  if (bitmap_bit_p (nonzero_vars, indx))
    return;

  /* Mark it in the global table.  */
  bitmap_set_bit (nonzero_vars, indx);

  /* Record this SSA_NAME so that we can reset the global table
     when we leave this block.  */
  VEC_safe_push (tree_on_heap, nonzero_vars_stack, var);
}

/* Enter a statement into the true/false expression hash table indicating
   that the condition COND has the value VALUE.  */

static void
record_cond (tree cond, tree value)
{
  struct expr_hash_elt *element = xmalloc (sizeof (struct expr_hash_elt));
  void **slot;

  initialize_hash_element (cond, value, element);

  slot = htab_find_slot_with_hash (avail_exprs, (void *)element,
				   element->hash, INSERT);
  if (*slot == NULL)
    {
      *slot = (void *) element;
      VEC_safe_push (tree_on_heap, avail_exprs_stack, cond);
    }
  else
    free (element);
}

/* Build a new conditional using NEW_CODE, OP0 and OP1 and store
   the new conditional into *p, then store a boolean_true_node
   into *(p + 1).  */
   
static void
build_and_record_new_cond (enum tree_code new_code, tree op0, tree op1, tree *p)
{
  *p = build2 (new_code, boolean_type_node, op0, op1);
  p++;
  *p = boolean_true_node;
}

/* Record that COND is true and INVERTED is false into the edge information
   structure.  Also record that any conditions dominated by COND are true
   as well.

   For example, if a < b is true, then a <= b must also be true.  */

static void
record_conditions (struct edge_info *edge_info, tree cond, tree inverted)
{
  tree op0, op1;

  if (!COMPARISON_CLASS_P (cond))
    return;

  op0 = TREE_OPERAND (cond, 0);
  op1 = TREE_OPERAND (cond, 1);

  switch (TREE_CODE (cond))
    {
    case LT_EXPR:
    case GT_EXPR:
      edge_info->max_cond_equivalences = 12;
      edge_info->cond_equivalences = xmalloc (12 * sizeof (tree));
      build_and_record_new_cond ((TREE_CODE (cond) == LT_EXPR
				  ? LE_EXPR : GE_EXPR),
				 op0, op1, &edge_info->cond_equivalences[4]);
      build_and_record_new_cond (ORDERED_EXPR, op0, op1,
				 &edge_info->cond_equivalences[6]);
      build_and_record_new_cond (NE_EXPR, op0, op1,
				 &edge_info->cond_equivalences[8]);
      build_and_record_new_cond (LTGT_EXPR, op0, op1,
				 &edge_info->cond_equivalences[10]);
      break;

    case GE_EXPR:
    case LE_EXPR:
      edge_info->max_cond_equivalences = 6;
      edge_info->cond_equivalences = xmalloc (6 * sizeof (tree));
      build_and_record_new_cond (ORDERED_EXPR, op0, op1,
				 &edge_info->cond_equivalences[4]);
      break;

    case EQ_EXPR:
      edge_info->max_cond_equivalences = 10;
      edge_info->cond_equivalences = xmalloc (10 * sizeof (tree));
      build_and_record_new_cond (ORDERED_EXPR, op0, op1,
				 &edge_info->cond_equivalences[4]);
      build_and_record_new_cond (LE_EXPR, op0, op1,
				 &edge_info->cond_equivalences[6]);
      build_and_record_new_cond (GE_EXPR, op0, op1,
				 &edge_info->cond_equivalences[8]);
      break;

    case UNORDERED_EXPR:
      edge_info->max_cond_equivalences = 16;
      edge_info->cond_equivalences = xmalloc (16 * sizeof (tree));
      build_and_record_new_cond (NE_EXPR, op0, op1,
				 &edge_info->cond_equivalences[4]);
      build_and_record_new_cond (UNLE_EXPR, op0, op1,
				 &edge_info->cond_equivalences[6]);
      build_and_record_new_cond (UNGE_EXPR, op0, op1,
				 &edge_info->cond_equivalences[8]);
      build_and_record_new_cond (UNEQ_EXPR, op0, op1,
				 &edge_info->cond_equivalences[10]);
      build_and_record_new_cond (UNLT_EXPR, op0, op1,
				 &edge_info->cond_equivalences[12]);
      build_and_record_new_cond (UNGT_EXPR, op0, op1,
				 &edge_info->cond_equivalences[14]);
      break;

    case UNLT_EXPR:
    case UNGT_EXPR:
      edge_info->max_cond_equivalences = 8;
      edge_info->cond_equivalences = xmalloc (8 * sizeof (tree));
      build_and_record_new_cond ((TREE_CODE (cond) == UNLT_EXPR
				  ? UNLE_EXPR : UNGE_EXPR),
				 op0, op1, &edge_info->cond_equivalences[4]);
      build_and_record_new_cond (NE_EXPR, op0, op1,
				 &edge_info->cond_equivalences[6]);
      break;

    case UNEQ_EXPR:
      edge_info->max_cond_equivalences = 8;
      edge_info->cond_equivalences = xmalloc (8 * sizeof (tree));
      build_and_record_new_cond (UNLE_EXPR, op0, op1,
				 &edge_info->cond_equivalences[4]);
      build_and_record_new_cond (UNGE_EXPR, op0, op1,
				 &edge_info->cond_equivalences[6]);
      break;

    case LTGT_EXPR:
      edge_info->max_cond_equivalences = 8;
      edge_info->cond_equivalences = xmalloc (8 * sizeof (tree));
      build_and_record_new_cond (NE_EXPR, op0, op1,
				 &edge_info->cond_equivalences[4]);
      build_and_record_new_cond (ORDERED_EXPR, op0, op1,
				 &edge_info->cond_equivalences[6]);
      break;

    default:
      edge_info->max_cond_equivalences = 4;
      edge_info->cond_equivalences = xmalloc (4 * sizeof (tree));
      break;
    }

  /* Now store the original true and false conditions into the first
     two slots.  */
  edge_info->cond_equivalences[0] = cond;
  edge_info->cond_equivalences[1] = boolean_true_node;
  edge_info->cond_equivalences[2] = inverted;
  edge_info->cond_equivalences[3] = boolean_false_node;
}

/* A helper function for record_const_or_copy and record_equality.
   Do the work of recording the value and undo info.  */

static void
record_const_or_copy_1 (tree x, tree y, tree prev_x)
{
  SSA_NAME_VALUE (x) = y;

  VEC_safe_push (tree_on_heap, const_and_copies_stack, prev_x);
  VEC_safe_push (tree_on_heap, const_and_copies_stack, x);
}


/* Return the loop depth of the basic block of the defining statement of X.
   This number should not be treated as absolutely correct because the loop
   information may not be completely up-to-date when dom runs.  However, it
   will be relatively correct, and as more passes are taught to keep loop info
   up to date, the result will become more and more accurate.  */

static int
loop_depth_of_name (tree x)
{
  tree defstmt;
  basic_block defbb;

  /* If it's not an SSA_NAME, we have no clue where the definition is.  */
  if (TREE_CODE (x) != SSA_NAME)
    return 0;

  /* Otherwise return the loop depth of the defining statement's bb.
     Note that there may not actually be a bb for this statement, if the
     ssa_name is live on entry.  */
  defstmt = SSA_NAME_DEF_STMT (x);
  defbb = bb_for_stmt (defstmt);
  if (!defbb)
    return 0;

  return defbb->loop_depth;
}


/* Record that X is equal to Y in const_and_copies.  Record undo
   information in the block-local vector.  */

static void
record_const_or_copy (tree x, tree y)
{
  tree prev_x = SSA_NAME_VALUE (x);

  if (TREE_CODE (y) == SSA_NAME)
    {
      tree tmp = SSA_NAME_VALUE (y);
      if (tmp)
	y = tmp;
    }

  record_const_or_copy_1 (x, y, prev_x);
}

/* Similarly, but assume that X and Y are the two operands of an EQ_EXPR.
   This constrains the cases in which we may treat this as assignment.  */

static void
record_equality (tree x, tree y)
{
  tree prev_x = NULL, prev_y = NULL;

  if (TREE_CODE (x) == SSA_NAME)
    prev_x = SSA_NAME_VALUE (x);
  if (TREE_CODE (y) == SSA_NAME)
    prev_y = SSA_NAME_VALUE (y);

  /* If one of the previous values is invariant, or invariant in more loops
     (by depth), then use that.
     Otherwise it doesn't matter which value we choose, just so
     long as we canonicalize on one value.  */
  if (TREE_INVARIANT (y))
    ;
  else if (TREE_INVARIANT (x) || (loop_depth_of_name (x) <= loop_depth_of_name (y)))
    prev_x = x, x = y, y = prev_x, prev_x = prev_y;
  else if (prev_x && TREE_INVARIANT (prev_x))
    x = y, y = prev_x, prev_x = prev_y;
  else if (prev_y && TREE_CODE (prev_y) != VALUE_HANDLE)
    y = prev_y;

  /* After the swapping, we must have one SSA_NAME.  */
  if (TREE_CODE (x) != SSA_NAME)
    return;

  /* For IEEE, -0.0 == 0.0, so we don't necessarily know the sign of a
     variable compared against zero.  If we're honoring signed zeros,
     then we cannot record this value unless we know that the value is
     nonzero.  */
  if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (x)))
      && (TREE_CODE (y) != REAL_CST
	  || REAL_VALUES_EQUAL (dconst0, TREE_REAL_CST (y))))
    return;

  record_const_or_copy_1 (x, y, prev_x);
}

/* Return true, if it is ok to do folding of an associative expression.
   EXP is the tree for the associative expression.  */ 

static inline bool
unsafe_associative_fp_binop (tree exp)
{
  enum tree_code code = TREE_CODE (exp);
  return !(!flag_unsafe_math_optimizations
           && (code == MULT_EXPR || code == PLUS_EXPR
	       || code == MINUS_EXPR)
           && FLOAT_TYPE_P (TREE_TYPE (exp)));
}

/* STMT is a MODIFY_EXPR for which we were unable to find RHS in the
   hash tables.  Try to simplify the RHS using whatever equivalences
   we may have recorded.

   If we are able to simplify the RHS, then lookup the simplified form in
   the hash table and return the result.  Otherwise return NULL.  */

static tree
simplify_rhs_and_lookup_avail_expr (struct dom_walk_data *walk_data,
				    tree stmt, int insert)
{
  tree rhs = TREE_OPERAND (stmt, 1);
  enum tree_code rhs_code = TREE_CODE (rhs);
  tree result = NULL;

  /* If we have lhs = ~x, look and see if we earlier had x = ~y.
     In which case we can change this statement to be lhs = y.
     Which can then be copy propagated. 

     Similarly for negation.  */
  if ((rhs_code == BIT_NOT_EXPR || rhs_code == NEGATE_EXPR)
      && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
    {
      /* Get the definition statement for our RHS.  */
      tree rhs_def_stmt = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 0));

      /* See if the RHS_DEF_STMT has the same form as our statement.  */
      if (TREE_CODE (rhs_def_stmt) == MODIFY_EXPR
	  && TREE_CODE (TREE_OPERAND (rhs_def_stmt, 1)) == rhs_code)
	{
	  tree rhs_def_operand;

	  rhs_def_operand = TREE_OPERAND (TREE_OPERAND (rhs_def_stmt, 1), 0);

	  /* Verify that RHS_DEF_OPERAND is a suitable SSA variable.  */
	  if (TREE_CODE (rhs_def_operand) == SSA_NAME
	      && ! SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs_def_operand))
	    result = update_rhs_and_lookup_avail_expr (stmt,
						       rhs_def_operand,
						       insert);
	}
    }

  /* If we have z = (x OP C1), see if we earlier had x = y OP C2.
     If OP is associative, create and fold (y OP C2) OP C1 which
     should result in (y OP C3), use that as the RHS for the
     assignment.  Add minus to this, as we handle it specially below.  */
  if ((associative_tree_code (rhs_code) || rhs_code == MINUS_EXPR)
      && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
      && is_gimple_min_invariant (TREE_OPERAND (rhs, 1)))
    {
      tree rhs_def_stmt = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 0));

      /* See if the RHS_DEF_STMT has the same form as our statement.  */
      if (TREE_CODE (rhs_def_stmt) == MODIFY_EXPR)
	{
	  tree rhs_def_rhs = TREE_OPERAND (rhs_def_stmt, 1);
	  enum tree_code rhs_def_code = TREE_CODE (rhs_def_rhs);

	  if ((rhs_code == rhs_def_code && unsafe_associative_fp_binop (rhs))
	      || (rhs_code == PLUS_EXPR && rhs_def_code == MINUS_EXPR)
	      || (rhs_code == MINUS_EXPR && rhs_def_code == PLUS_EXPR))
	    {
	      tree def_stmt_op0 = TREE_OPERAND (rhs_def_rhs, 0);
	      tree def_stmt_op1 = TREE_OPERAND (rhs_def_rhs, 1);

	      if (TREE_CODE (def_stmt_op0) == SSA_NAME
		  && ! SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def_stmt_op0)
		  && is_gimple_min_invariant (def_stmt_op1))
		{
		  tree outer_const = TREE_OPERAND (rhs, 1);
		  tree type = TREE_TYPE (TREE_OPERAND (stmt, 0));
		  tree t;

		  /* If we care about correct floating point results, then
		     don't fold x + c1 - c2.  Note that we need to take both
		     the codes and the signs to figure this out.  */
		  if (FLOAT_TYPE_P (type)
		      && !flag_unsafe_math_optimizations
		      && (rhs_def_code == PLUS_EXPR
			  || rhs_def_code == MINUS_EXPR))
		    {
		      bool neg = false;

		      neg ^= (rhs_code == MINUS_EXPR);
		      neg ^= (rhs_def_code == MINUS_EXPR);
		      neg ^= real_isneg (TREE_REAL_CST_PTR (outer_const));
		      neg ^= real_isneg (TREE_REAL_CST_PTR (def_stmt_op1));

		      if (neg)
			goto dont_fold_assoc;
		    }

		  /* Ho hum.  So fold will only operate on the outermost
		     thingy that we give it, so we have to build the new
		     expression in two pieces.  This requires that we handle
		     combinations of plus and minus.  */
		  if (rhs_def_code != rhs_code)
		    {
		      if (rhs_def_code == MINUS_EXPR)
		        t = build (MINUS_EXPR, type, outer_const, def_stmt_op1);
		      else
		        t = build (MINUS_EXPR, type, def_stmt_op1, outer_const);
		      rhs_code = PLUS_EXPR;
		    }
		  else if (rhs_def_code == MINUS_EXPR)
		    t = build (PLUS_EXPR, type, def_stmt_op1, outer_const);
		  else
		    t = build (rhs_def_code, type, def_stmt_op1, outer_const);
		  t = local_fold (t);
		  t = build (rhs_code, type, def_stmt_op0, t);
		  t = local_fold (t);

		  /* If the result is a suitable looking gimple expression,
		     then use it instead of the original for STMT.  */
		  if (TREE_CODE (t) == SSA_NAME
		      || (UNARY_CLASS_P (t)
			  && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME)
		      || ((BINARY_CLASS_P (t) || COMPARISON_CLASS_P (t))
			  && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME
			  && is_gimple_val (TREE_OPERAND (t, 1))))
		    result = update_rhs_and_lookup_avail_expr (stmt, t, insert);
		}
	    }
	}
 dont_fold_assoc:;
    }

  /* Transform TRUNC_DIV_EXPR and TRUNC_MOD_EXPR into RSHIFT_EXPR
     and BIT_AND_EXPR respectively if the first operand is greater
     than zero and the second operand is an exact power of two.  */
  if ((rhs_code == TRUNC_DIV_EXPR || rhs_code == TRUNC_MOD_EXPR)
      && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (rhs, 0)))
      && integer_pow2p (TREE_OPERAND (rhs, 1)))
    {
      tree val;
      tree op = TREE_OPERAND (rhs, 0);

      if (TYPE_UNSIGNED (TREE_TYPE (op)))
	{
	  val = integer_one_node;
	}
      else
	{
	  tree dummy_cond = walk_data->global_data;

	  if (! dummy_cond)
	    {
	      dummy_cond = build (GT_EXPR, boolean_type_node,
				  op, integer_zero_node);
	      dummy_cond = build (COND_EXPR, void_type_node,
				  dummy_cond, NULL, NULL);
	      walk_data->global_data = dummy_cond;
	    }
          else
	    {
	      TREE_SET_CODE (COND_EXPR_COND (dummy_cond), GT_EXPR);
	      TREE_OPERAND (COND_EXPR_COND (dummy_cond), 0) = op;
	      TREE_OPERAND (COND_EXPR_COND (dummy_cond), 1)
		= integer_zero_node;
	    }
	  val = simplify_cond_and_lookup_avail_expr (dummy_cond, NULL, false);
	}

      if (val && integer_onep (val))
	{
	  tree t;
	  tree op0 = TREE_OPERAND (rhs, 0);
	  tree op1 = TREE_OPERAND (rhs, 1);

	  if (rhs_code == TRUNC_DIV_EXPR)
	    t = build (RSHIFT_EXPR, TREE_TYPE (op0), op0,
		       build_int_cst (NULL_TREE, tree_log2 (op1)));
	  else
	    t = build (BIT_AND_EXPR, TREE_TYPE (op0), op0,
		       local_fold (build (MINUS_EXPR, TREE_TYPE (op1),
					  op1, integer_one_node)));

	  result = update_rhs_and_lookup_avail_expr (stmt, t, insert);
	}
    }

  /* Transform ABS (X) into X or -X as appropriate.  */
  if (rhs_code == ABS_EXPR
      && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (rhs, 0))))
    {
      tree val;
      tree op = TREE_OPERAND (rhs, 0);
      tree type = TREE_TYPE (op);

      if (TYPE_UNSIGNED (type))
	{
	  val = integer_zero_node;
	}
      else
	{
	  tree dummy_cond = walk_data->global_data;

	  if (! dummy_cond)
	    {
	      dummy_cond = build (LE_EXPR, boolean_type_node,
				  op, integer_zero_node);
	      dummy_cond = build (COND_EXPR, void_type_node,
				  dummy_cond, NULL, NULL);
	      walk_data->global_data = dummy_cond;
	    }
	  else
	    {
	      TREE_SET_CODE (COND_EXPR_COND (dummy_cond), LE_EXPR);
	      TREE_OPERAND (COND_EXPR_COND (dummy_cond), 0) = op;
	      TREE_OPERAND (COND_EXPR_COND (dummy_cond), 1)
		= build_int_cst (type, 0);
	    }
	  val = simplify_cond_and_lookup_avail_expr (dummy_cond, NULL, false);

	  if (!val)
	    {
	      TREE_SET_CODE (COND_EXPR_COND (dummy_cond), GE_EXPR);
	      TREE_OPERAND (COND_EXPR_COND (dummy_cond), 0) = op;
	      TREE_OPERAND (COND_EXPR_COND (dummy_cond), 1)
		= build_int_cst (type, 0);

	      val = simplify_cond_and_lookup_avail_expr (dummy_cond,
							 NULL, false);

	      if (val)
		{
		  if (integer_zerop (val))
		    val = integer_one_node;
		  else if (integer_onep (val))
		    val = integer_zero_node;
		}
	    }
	}

      if (val
	  && (integer_onep (val) || integer_zerop (val)))
	{
	  tree t;

	  if (integer_onep (val))
	    t = build1 (NEGATE_EXPR, TREE_TYPE (op), op);
	  else
	    t = op;

	  result = update_rhs_and_lookup_avail_expr (stmt, t, insert);
	}
    }

  /* Optimize *"foo" into 'f'.  This is done here rather than
     in fold to avoid problems with stuff like &*"foo".  */
  if (TREE_CODE (rhs) == INDIRECT_REF || TREE_CODE (rhs) == ARRAY_REF)
    {
      tree t = fold_read_from_constant_string (rhs);

      if (t)
        result = update_rhs_and_lookup_avail_expr (stmt, t, insert);
    }

  return result;
}

/* COND is a condition of the form:

     x == const or x != const

   Look back to x's defining statement and see if x is defined as

     x = (type) y;

   If const is unchanged if we convert it to type, then we can build
   the equivalent expression:


      y == const or y != const

   Which may allow further optimizations.

   Return the equivalent comparison or NULL if no such equivalent comparison
   was found.  */

static tree
find_equivalent_equality_comparison (tree cond)
{
  tree op0 = TREE_OPERAND (cond, 0);
  tree op1 = TREE_OPERAND (cond, 1);
  tree def_stmt = SSA_NAME_DEF_STMT (op0);

  /* OP0 might have been a parameter, so first make sure it
     was defined by a MODIFY_EXPR.  */
  if (def_stmt && TREE_CODE (def_stmt) == MODIFY_EXPR)
    {
      tree def_rhs = TREE_OPERAND (def_stmt, 1);


      /* If either operand to the comparison is a pointer to
	 a function, then we can not apply this optimization
	 as some targets require function pointers to be
	 canonicalized and in this case this optimization would
	 eliminate a necessary canonicalization.  */
      if ((POINTER_TYPE_P (TREE_TYPE (op0))
	   && TREE_CODE (TREE_TYPE (TREE_TYPE (op0))) == FUNCTION_TYPE)
	  || (POINTER_TYPE_P (TREE_TYPE (op1))
	      && TREE_CODE (TREE_TYPE (TREE_TYPE (op1))) == FUNCTION_TYPE))
	return NULL;
	      
      /* Now make sure the RHS of the MODIFY_EXPR is a typecast.  */
      if ((TREE_CODE (def_rhs) == NOP_EXPR
	   || TREE_CODE (def_rhs) == CONVERT_EXPR)
	  && TREE_CODE (TREE_OPERAND (def_rhs, 0)) == SSA_NAME)
	{
	  tree def_rhs_inner = TREE_OPERAND (def_rhs, 0);
	  tree def_rhs_inner_type = TREE_TYPE (def_rhs_inner);
	  tree new;

	  if (TYPE_PRECISION (def_rhs_inner_type)
	      > TYPE_PRECISION (TREE_TYPE (def_rhs)))
	    return NULL;

	  /* If the inner type of the conversion is a pointer to
	     a function, then we can not apply this optimization
	     as some targets require function pointers to be
	     canonicalized.  This optimization would result in
	     canonicalization of the pointer when it was not originally
	     needed/intended.  */
	  if (POINTER_TYPE_P (def_rhs_inner_type)
	      && TREE_CODE (TREE_TYPE (def_rhs_inner_type)) == FUNCTION_TYPE)
	    return NULL;

	  /* What we want to prove is that if we convert OP1 to
	     the type of the object inside the NOP_EXPR that the
	     result is still equivalent to SRC. 

	     If that is true, the build and return new equivalent
	     condition which uses the source of the typecast and the
	     new constant (which has only changed its type).  */
	  new = build1 (TREE_CODE (def_rhs), def_rhs_inner_type, op1);
	  new = local_fold (new);
	  if (is_gimple_val (new) && tree_int_cst_equal (new, op1))
	    return build (TREE_CODE (cond), TREE_TYPE (cond),
			  def_rhs_inner, new);
	}
    }
  return NULL;
}

/* STMT is a COND_EXPR for which we could not trivially determine its
   result.  This routine attempts to find equivalent forms of the
   condition which we may be able to optimize better.  It also 
   uses simple value range propagation to optimize conditionals.  */

static tree
simplify_cond_and_lookup_avail_expr (tree stmt,
				     stmt_ann_t ann,
				     int insert)
{
  tree cond = COND_EXPR_COND (stmt);

  if (COMPARISON_CLASS_P (cond))
    {
      tree op0 = TREE_OPERAND (cond, 0);
      tree op1 = TREE_OPERAND (cond, 1);

      if (TREE_CODE (op0) == SSA_NAME && is_gimple_min_invariant (op1))
	{
	  int limit;
	  tree low, high, cond_low, cond_high;
	  int lowequal, highequal, swapped, no_overlap, subset, cond_inverted;
	  varray_type vrp_records;
	  struct vrp_element *element;
	  struct vrp_hash_elt vrp_hash_elt, *vrp_hash_elt_p;
	  void **slot;

	  /* First see if we have test of an SSA_NAME against a constant
	     where the SSA_NAME is defined by an earlier typecast which
	     is irrelevant when performing tests against the given
	     constant.  */
	  if (TREE_CODE (cond) == EQ_EXPR || TREE_CODE (cond) == NE_EXPR)
	    {
	      tree new_cond = find_equivalent_equality_comparison (cond);

	      if (new_cond)
		{
		  /* Update the statement to use the new equivalent
		     condition.  */
		  COND_EXPR_COND (stmt) = new_cond;

		  /* If this is not a real stmt, ann will be NULL and we
		     avoid processing the operands.  */
		  if (ann)
		    modify_stmt (stmt);

		  /* Lookup the condition and return its known value if it
		     exists.  */
		  new_cond = lookup_avail_expr (stmt, insert);
		  if (new_cond)
		    return new_cond;

		  /* The operands have changed, so update op0 and op1.  */
		  op0 = TREE_OPERAND (cond, 0);
		  op1 = TREE_OPERAND (cond, 1);
		}
	    }

	  /* Consult the value range records for this variable (if they exist)
	     to see if we can eliminate or simplify this conditional. 

	     Note two tests are necessary to determine no records exist.
	     First we have to see if the virtual array exists, if it 
	     exists, then we have to check its active size. 

	     Also note the vast majority of conditionals are not testing
	     a variable which has had its range constrained by an earlier
	     conditional.  So this filter avoids a lot of unnecessary work.  */
	  vrp_hash_elt.var = op0;
	  vrp_hash_elt.records = NULL;
          slot = htab_find_slot (vrp_data, &vrp_hash_elt, NO_INSERT);
          if (slot == NULL)
	    return NULL;

	  vrp_hash_elt_p = (struct vrp_hash_elt *) *slot;
	  vrp_records = vrp_hash_elt_p->records;
	  if (vrp_records == NULL)
	    return NULL;

	  limit = VARRAY_ACTIVE_SIZE (vrp_records);

	  /* If we have no value range records for this variable, or we are
	     unable to extract a range for this condition, then there is
	     nothing to do.  */
	  if (limit == 0
	      || ! extract_range_from_cond (cond, &cond_high,
					    &cond_low, &cond_inverted))
	    return NULL;

	  /* We really want to avoid unnecessary computations of range
	     info.  So all ranges are computed lazily; this avoids a
	     lot of unnecessary work.  i.e., we record the conditional,
	     but do not process how it constrains the variable's 
	     potential values until we know that processing the condition
	     could be helpful.

	     However, we do not want to have to walk a potentially long
	     list of ranges, nor do we want to compute a variable's
	     range more than once for a given path.

	     Luckily, each time we encounter a conditional that can not
	     be otherwise optimized we will end up here and we will
	     compute the necessary range information for the variable
	     used in this condition.

	     Thus you can conclude that there will never be more than one
	     conditional associated with a variable which has not been
	     processed.  So we never need to merge more than one new
	     conditional into the current range. 

	     These properties also help us avoid unnecessary work.  */
	   element
	     = (struct vrp_element *)VARRAY_GENERIC_PTR (vrp_records, limit - 1);

	  if (element->high && element->low)
	    {
	      /* The last element has been processed, so there is no range
		 merging to do, we can simply use the high/low values
		 recorded in the last element.  */
	      low = element->low;
	      high = element->high;
	    }
	  else
	    {
	      tree tmp_high, tmp_low;
	      int dummy;

	      /* The last element has not been processed.  Process it now.
		 record_range should ensure for cond inverted is not set.
		 This call can only fail if cond is x < min or x > max,
		 which fold should have optimized into false.
		 If that doesn't happen, just pretend all values are
		 in the range.  */
	      if (! extract_range_from_cond (element->cond, &tmp_high,
					     &tmp_low, &dummy))
		gcc_unreachable ();
	      else
		gcc_assert (dummy == 0);

	      /* If this is the only element, then no merging is necessary, 
		 the high/low values from extract_range_from_cond are all
		 we need.  */
	      if (limit == 1)
		{
		  low = tmp_low;
		  high = tmp_high;
		}
	      else
		{
		  /* Get the high/low value from the previous element.  */
		  struct vrp_element *prev
		    = (struct vrp_element *)VARRAY_GENERIC_PTR (vrp_records,
								limit - 2);
		  low = prev->low;
		  high = prev->high;

		  /* Merge in this element's range with the range from the
		     previous element.

		     The low value for the merged range is the maximum of
		     the previous low value and the low value of this record.

		     Similarly the high value for the merged range is the
		     minimum of the previous high value and the high value of
		     this record.  */
		  low = (tree_int_cst_compare (low, tmp_low) == 1
			 ? low : tmp_low);
		  high = (tree_int_cst_compare (high, tmp_high) == -1
			  ? high : tmp_high);
		}

	      /* And record the computed range.  */
	      element->low = low;
	      element->high = high;

	    }

	  /* After we have constrained this variable's potential values,
	     we try to determine the result of the given conditional.

	     To simplify later tests, first determine if the current
	     low value is the same low value as the conditional.
	     Similarly for the current high value and the high value
	     for the conditional.  */
	  lowequal = tree_int_cst_equal (low, cond_low);
	  highequal = tree_int_cst_equal (high, cond_high);

	  if (lowequal && highequal)
	    return (cond_inverted ? boolean_false_node : boolean_true_node);

	  /* To simplify the overlap/subset tests below we may want
	     to swap the two ranges so that the larger of the two
	     ranges occurs "first".  */
	  swapped = 0;
	  if (tree_int_cst_compare (low, cond_low) == 1
	      || (lowequal 
		  && tree_int_cst_compare (cond_high, high) == 1))
	    {
	      tree temp;

	      swapped = 1;
	      temp = low;
	      low = cond_low;
	      cond_low = temp;
	      temp = high;
	      high = cond_high;
	      cond_high = temp;
	    }

	  /* Now determine if there is no overlap in the ranges
	     or if the second range is a subset of the first range.  */
	  no_overlap = tree_int_cst_lt (high, cond_low);
	  subset = tree_int_cst_compare (cond_high, high) != 1;

	  /* If there was no overlap in the ranges, then this conditional
	     always has a false value (unless we had to invert this
	     conditional, in which case it always has a true value).  */
	  if (no_overlap)
	    return (cond_inverted ? boolean_true_node : boolean_false_node);

	  /* If the current range is a subset of the condition's range,
	     then this conditional always has a true value (unless we
	     had to invert this conditional, in which case it always
	     has a true value).  */
	  if (subset && swapped)
	    return (cond_inverted ? boolean_false_node : boolean_true_node);

	  /* We were unable to determine the result of the conditional.
	     However, we may be able to simplify the conditional.  First
	     merge the ranges in the same manner as range merging above.  */
	  low = tree_int_cst_compare (low, cond_low) == 1 ? low : cond_low;
	  high = tree_int_cst_compare (high, cond_high) == -1 ? high : cond_high;
	  
	  /* If the range has converged to a single point, then turn this
	     into an equality comparison.  */
	  if (TREE_CODE (cond) != EQ_EXPR
	      && TREE_CODE (cond) != NE_EXPR
	      && tree_int_cst_equal (low, high))
	    {
	      TREE_SET_CODE (cond, EQ_EXPR);
	      TREE_OPERAND (cond, 1) = high;
	    }
	}
    }
  return 0;
}

/* STMT is a SWITCH_EXPR for which we could not trivially determine its
   result.  This routine attempts to find equivalent forms of the
   condition which we may be able to optimize better.  */

static tree
simplify_switch_and_lookup_avail_expr (tree stmt, int insert)
{
  tree cond = SWITCH_COND (stmt);
  tree def, to, ti;

  /* The optimization that we really care about is removing unnecessary
     casts.  That will let us do much better in propagating the inferred
     constant at the switch target.  */
  if (TREE_CODE (cond) == SSA_NAME)
    {
      def = SSA_NAME_DEF_STMT (cond);
      if (TREE_CODE (def) == MODIFY_EXPR)
	{
	  def = TREE_OPERAND (def, 1);
	  if (TREE_CODE (def) == NOP_EXPR)
	    {
	      int need_precision;
	      bool fail;

	      def = TREE_OPERAND (def, 0);

#ifdef ENABLE_CHECKING
	      /* ??? Why was Jeff testing this?  We are gimple...  */
	      gcc_assert (is_gimple_val (def));
#endif

	      to = TREE_TYPE (cond);
	      ti = TREE_TYPE (def);

	      /* If we have an extension that preserves value, then we
		 can copy the source value into the switch.  */

	      need_precision = TYPE_PRECISION (ti);
	      fail = false;
	      if (TYPE_UNSIGNED (to) && !TYPE_UNSIGNED (ti))
		fail = true;
	      else if (!TYPE_UNSIGNED (to) && TYPE_UNSIGNED (ti))
		need_precision += 1;
	      if (TYPE_PRECISION (to) < need_precision)
		fail = true;

	      if (!fail)
		{
		  SWITCH_COND (stmt) = def;
		  modify_stmt (stmt);

		  return lookup_avail_expr (stmt, insert);
		}
	    }
	}
    }

  return 0;
}


/* CONST_AND_COPIES is a table which maps an SSA_NAME to the current
   known value for that SSA_NAME (or NULL if no value is known).  

   NONZERO_VARS is the set SSA_NAMES known to have a nonzero value,
   even if we don't know their precise value.

   Propagate values from CONST_AND_COPIES and NONZERO_VARS into the PHI
   nodes of the successors of BB.  */

static void
cprop_into_successor_phis (basic_block bb, bitmap nonzero_vars)
{
  edge e;
  edge_iterator ei;

  /* This can get rather expensive if the implementation is naive in
     how it finds the phi alternative associated with a particular edge.  */
  FOR_EACH_EDGE (e, ei, bb->succs)
    {
      tree phi;
      int indx;

      /* If this is an abnormal edge, then we do not want to copy propagate
	 into the PHI alternative associated with this edge.  */
      if (e->flags & EDGE_ABNORMAL)
	continue;

      phi = phi_nodes (e->dest);
      if (! phi)
	continue;

      indx = e->dest_idx;
      for ( ; phi; phi = PHI_CHAIN (phi))
	{
	  tree new;
	  use_operand_p orig_p;
	  tree orig;

	  /* The alternative may be associated with a constant, so verify
	     it is an SSA_NAME before doing anything with it.  */
	  orig_p = PHI_ARG_DEF_PTR (phi, indx);
	  orig = USE_FROM_PTR (orig_p);
	  if (TREE_CODE (orig) != SSA_NAME)
	    continue;

	  /* If the alternative is known to have a nonzero value, record
	     that fact in the PHI node itself for future use.  */
	  if (bitmap_bit_p (nonzero_vars, SSA_NAME_VERSION (orig)))
	    PHI_ARG_NONZERO (phi, indx) = true;

	  /* If we have *ORIG_P in our constant/copy table, then replace
	     ORIG_P with its value in our constant/copy table.  */
	  new = SSA_NAME_VALUE (orig);
	  if (new
	      && (TREE_CODE (new) == SSA_NAME
		  || is_gimple_min_invariant (new))
	      && may_propagate_copy (orig, new))
	    {
	      propagate_value (orig_p, new);
	    }
	}
    }
}

/* We have finished optimizing BB, record any information implied by
   taking a specific outgoing edge from BB.  */

static void
record_edge_info (basic_block bb)
{
  block_stmt_iterator bsi = bsi_last (bb);
  struct edge_info *edge_info;

  if (! bsi_end_p (bsi))
    {
      tree stmt = bsi_stmt (bsi);

      if (stmt && TREE_CODE (stmt) == SWITCH_EXPR)
	{
	  tree cond = SWITCH_COND (stmt);

	  if (TREE_CODE (cond) == SSA_NAME)
	    {
	      tree labels = SWITCH_LABELS (stmt);
	      int i, n_labels = TREE_VEC_LENGTH (labels);
	      tree *info = xcalloc (n_basic_blocks, sizeof (tree));
	      edge e;
	      edge_iterator ei;

	      for (i = 0; i < n_labels; i++)
		{
		  tree label = TREE_VEC_ELT (labels, i);
		  basic_block target_bb = label_to_block (CASE_LABEL (label));

		  if (CASE_HIGH (label)
		      || !CASE_LOW (label)
		      || info[target_bb->index])
		    info[target_bb->index] = error_mark_node;
		  else
		    info[target_bb->index] = label;
		}

	      FOR_EACH_EDGE (e, ei, bb->succs)
		{
		  basic_block target_bb = e->dest;
		  tree node = info[target_bb->index];

		  if (node != NULL && node != error_mark_node)
		    {
		      tree x = fold_convert (TREE_TYPE (cond), CASE_LOW (node));
		      edge_info = allocate_edge_info (e);
		      edge_info->lhs = cond;
		      edge_info->rhs = x;
		    }
		}
	      free (info);
	    }
	}

      /* A COND_EXPR may create equivalences too.  */
      if (stmt && TREE_CODE (stmt) == COND_EXPR)
	{
	  tree cond = COND_EXPR_COND (stmt);
	  edge true_edge;
	  edge false_edge;

	  extract_true_false_edges_from_block (bb, &true_edge, &false_edge);

	  /* If the conditional is a single variable 'X', record 'X = 1'
	     for the true edge and 'X = 0' on the false edge.  */
	  if (SSA_VAR_P (cond))
	    {
	      struct edge_info *edge_info;

	      edge_info = allocate_edge_info (true_edge);
	      edge_info->lhs = cond;
	      edge_info->rhs = constant_boolean_node (1, TREE_TYPE (cond));

	      edge_info = allocate_edge_info (false_edge);
	      edge_info->lhs = cond;
	      edge_info->rhs = constant_boolean_node (0, TREE_TYPE (cond));
	    }
	  /* Equality tests may create one or two equivalences.  */
	  else if (COMPARISON_CLASS_P (cond))
	    {
	      tree op0 = TREE_OPERAND (cond, 0);
	      tree op1 = TREE_OPERAND (cond, 1);

	      /* Special case comparing booleans against a constant as we
		 know the value of OP0 on both arms of the branch.  i.e., we
		 can record an equivalence for OP0 rather than COND.  */
	      if ((TREE_CODE (cond) == EQ_EXPR || TREE_CODE (cond) == NE_EXPR)
		  && TREE_CODE (op0) == SSA_NAME
		  && TREE_CODE (TREE_TYPE (op0)) == BOOLEAN_TYPE
		  && is_gimple_min_invariant (op1))
		{
		  if (TREE_CODE (cond) == EQ_EXPR)
		    {
		      edge_info = allocate_edge_info (true_edge);
		      edge_info->lhs = op0;
		      edge_info->rhs = (integer_zerop (op1)
					    ? boolean_false_node
					    : boolean_true_node);

		      edge_info = allocate_edge_info (false_edge);
		      edge_info->lhs = op0;
		      edge_info->rhs = (integer_zerop (op1)
					    ? boolean_true_node
					    : boolean_false_node);
		    }
		  else
		    {
		      edge_info = allocate_edge_info (true_edge);
		      edge_info->lhs = op0;
		      edge_info->rhs = (integer_zerop (op1)
					    ? boolean_true_node
					    : boolean_false_node);

		      edge_info = allocate_edge_info (false_edge);
		      edge_info->lhs = op0;
		      edge_info->rhs = (integer_zerop (op1)
					    ? boolean_false_node
					    : boolean_true_node);
		    }
		}

	      else if (is_gimple_min_invariant (op0)
		       && (TREE_CODE (op1) == SSA_NAME
			   || is_gimple_min_invariant (op1)))
		{
		  tree inverted = invert_truthvalue (cond);
		  struct edge_info *edge_info;

		  edge_info = allocate_edge_info (true_edge);
		  record_conditions (edge_info, cond, inverted);

		  if (TREE_CODE (cond) == EQ_EXPR)
		    {
		      edge_info->lhs = op1;
		      edge_info->rhs = op0;
		    }

		  edge_info = allocate_edge_info (false_edge);
		  record_conditions (edge_info, inverted, cond);

		  if (TREE_CODE (cond) == NE_EXPR)
		    {
		      edge_info->lhs = op1;
		      edge_info->rhs = op0;
		    }
		}

	      else if (TREE_CODE (op0) == SSA_NAME
		       && (is_gimple_min_invariant (op1)
			   || TREE_CODE (op1) == SSA_NAME))
		{
		  tree inverted = invert_truthvalue (cond);
		  struct edge_info *edge_info;

		  edge_info = allocate_edge_info (true_edge);
		  record_conditions (edge_info, cond, inverted);

		  if (TREE_CODE (cond) == EQ_EXPR)
		    {
		      edge_info->lhs = op0;
		      edge_info->rhs = op1;
		    }

		  edge_info = allocate_edge_info (false_edge);
		  record_conditions (edge_info, inverted, cond);

		  if (TREE_CODE (cond) == NE_EXPR)
		    {
		      edge_info->lhs = op0;
		      edge_info->rhs = op1;
		    }
		}
	    }

	  /* ??? TRUTH_NOT_EXPR can create an equivalence too.  */
	}
    }
}

/* Propagate information from BB to its outgoing edges.

   This can include equivalency information implied by control statements
   at the end of BB and const/copy propagation into PHIs in BB's
   successor blocks.  */

static void
propagate_to_outgoing_edges (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
			     basic_block bb)
{
  
  record_edge_info (bb);
  cprop_into_successor_phis (bb, nonzero_vars);
}

/* Search for redundant computations in STMT.  If any are found, then
   replace them with the variable holding the result of the computation.

   If safe, record this expression into the available expression hash
   table.  */

static bool
eliminate_redundant_computations (struct dom_walk_data *walk_data,
				  tree stmt, stmt_ann_t ann)
{
  v_may_def_optype v_may_defs = V_MAY_DEF_OPS (ann);
  tree *expr_p, def = NULL_TREE;
  bool insert = true;
  tree cached_lhs;
  bool retval = false;

  if (TREE_CODE (stmt) == MODIFY_EXPR)
    def = TREE_OPERAND (stmt, 0);

  /* Certain expressions on the RHS can be optimized away, but can not
     themselves be entered into the hash tables.  */
  if (ann->makes_aliased_stores
      || ! def
      || TREE_CODE (def) != SSA_NAME
      || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def)
      || NUM_V_MAY_DEFS (v_may_defs) != 0)
    insert = false;

  /* Check if the expression has been computed before.  */
  cached_lhs = lookup_avail_expr (stmt, insert);

  /* If this is an assignment and the RHS was not in the hash table,
     then try to simplify the RHS and lookup the new RHS in the
     hash table.  */
  if (! cached_lhs && TREE_CODE (stmt) == MODIFY_EXPR)
    cached_lhs = simplify_rhs_and_lookup_avail_expr (walk_data, stmt, insert);
  /* Similarly if this is a COND_EXPR and we did not find its
     expression in the hash table, simplify the condition and
     try again.  */
  else if (! cached_lhs && TREE_CODE (stmt) == COND_EXPR)
    cached_lhs = simplify_cond_and_lookup_avail_expr (stmt, ann, insert);
  /* Similarly for a SWITCH_EXPR.  */
  else if (!cached_lhs && TREE_CODE (stmt) == SWITCH_EXPR)
    cached_lhs = simplify_switch_and_lookup_avail_expr (stmt, insert);

  opt_stats.num_exprs_considered++;

  /* Get a pointer to the expression we are trying to optimize.  */
  if (TREE_CODE (stmt) == COND_EXPR)
    expr_p = &COND_EXPR_COND (stmt);
  else if (TREE_CODE (stmt) == SWITCH_EXPR)
    expr_p = &SWITCH_COND (stmt);
  else if (TREE_CODE (stmt) == RETURN_EXPR && TREE_OPERAND (stmt, 0))
    expr_p = &TREE_OPERAND (TREE_OPERAND (stmt, 0), 1);
  else
    expr_p = &TREE_OPERAND (stmt, 1);

  /* It is safe to ignore types here since we have already done
     type checking in the hashing and equality routines.  In fact
     type checking here merely gets in the way of constant
     propagation.  Also, make sure that it is safe to propagate
     CACHED_LHS into *EXPR_P.  */
  if (cached_lhs
      && (TREE_CODE (cached_lhs) != SSA_NAME
	  || may_propagate_copy (*expr_p, cached_lhs)))
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "  Replaced redundant expr '");
	  print_generic_expr (dump_file, *expr_p, dump_flags);
	  fprintf (dump_file, "' with '");
	  print_generic_expr (dump_file, cached_lhs, dump_flags);
	   fprintf (dump_file, "'\n");
	}

      opt_stats.num_re++;

#if defined ENABLE_CHECKING
      gcc_assert (TREE_CODE (cached_lhs) == SSA_NAME
		  || is_gimple_min_invariant (cached_lhs));
#endif

      if (TREE_CODE (cached_lhs) == ADDR_EXPR
	  || (POINTER_TYPE_P (TREE_TYPE (*expr_p))
	      && is_gimple_min_invariant (cached_lhs)))
	retval = true;

      propagate_tree_value (expr_p, cached_lhs);
      modify_stmt (stmt);
    }
  return retval;
}

/* STMT, a MODIFY_EXPR, may create certain equivalences, in either
   the available expressions table or the const_and_copies table.
   Detect and record those equivalences.  */

static void
record_equivalences_from_stmt (tree stmt,
			       int may_optimize_p,
			       stmt_ann_t ann)
{
  tree lhs = TREE_OPERAND (stmt, 0);
  enum tree_code lhs_code = TREE_CODE (lhs);
  int i;

  if (lhs_code == SSA_NAME)
    {
      tree rhs = TREE_OPERAND (stmt, 1);

      /* Strip away any useless type conversions.  */
      STRIP_USELESS_TYPE_CONVERSION (rhs);

      /* If the RHS of the assignment is a constant or another variable that
	 may be propagated, register it in the CONST_AND_COPIES table.  We
	 do not need to record unwind data for this, since this is a true
	 assignment and not an equivalence inferred from a comparison.  All
	 uses of this ssa name are dominated by this assignment, so unwinding
	 just costs time and space.  */
      if (may_optimize_p
	  && (TREE_CODE (rhs) == SSA_NAME
	      || is_gimple_min_invariant (rhs)))
	SSA_NAME_VALUE (lhs) = rhs;

      /* alloca never returns zero and the address of a non-weak symbol
	 is never zero.  NOP_EXPRs and CONVERT_EXPRs can be completely
	 stripped as they do not affect this equivalence.  */
      while (TREE_CODE (rhs) == NOP_EXPR
	     || TREE_CODE (rhs) == CONVERT_EXPR)
        rhs = TREE_OPERAND (rhs, 0);

      if (alloca_call_p (rhs)
          || (TREE_CODE (rhs) == ADDR_EXPR
	      && DECL_P (TREE_OPERAND (rhs, 0))
	      && ! DECL_WEAK (TREE_OPERAND (rhs, 0))))
	record_var_is_nonzero (lhs);

      /* IOR of any value with a nonzero value will result in a nonzero
	 value.  Even if we do not know the exact result recording that
	 the result is nonzero is worth the effort.  */
      if (TREE_CODE (rhs) == BIT_IOR_EXPR
	  && integer_nonzerop (TREE_OPERAND (rhs, 1)))
	record_var_is_nonzero (lhs);
    }

  /* Look at both sides for pointer dereferences.  If we find one, then
     the pointer must be nonnull and we can enter that equivalence into
     the hash tables.  */
  if (flag_delete_null_pointer_checks)
    for (i = 0; i < 2; i++)
      {
	tree t = TREE_OPERAND (stmt, i);

	/* Strip away any COMPONENT_REFs.  */
	while (TREE_CODE (t) == COMPONENT_REF)
	  t = TREE_OPERAND (t, 0);

	/* Now see if this is a pointer dereference.  */
	if (INDIRECT_REF_P (t))
          {
	    tree op = TREE_OPERAND (t, 0);

	    /* If the pointer is a SSA variable, then enter new
	       equivalences into the hash table.  */
	    while (TREE_CODE (op) == SSA_NAME)
	      {
		tree def = SSA_NAME_DEF_STMT (op);

		record_var_is_nonzero (op);

		/* And walk up the USE-DEF chains noting other SSA_NAMEs
		   which are known to have a nonzero value.  */
		if (def
		    && TREE_CODE (def) == MODIFY_EXPR
		    && TREE_CODE (TREE_OPERAND (def, 1)) == NOP_EXPR)
		  op = TREE_OPERAND (TREE_OPERAND (def, 1), 0);
		else
		  break;
	      }
	  }
      }

  /* A memory store, even an aliased store, creates a useful
     equivalence.  By exchanging the LHS and RHS, creating suitable
     vops and recording the result in the available expression table,
     we may be able to expose more redundant loads.  */
  if (!ann->has_volatile_ops
      && (TREE_CODE (TREE_OPERAND (stmt, 1)) == SSA_NAME
	  || is_gimple_min_invariant (TREE_OPERAND (stmt, 1)))
      && !is_gimple_reg (lhs))
    {
      tree rhs = TREE_OPERAND (stmt, 1);
      tree new;

      /* FIXME: If the LHS of the assignment is a bitfield and the RHS
         is a constant, we need to adjust the constant to fit into the
         type of the LHS.  If the LHS is a bitfield and the RHS is not
	 a constant, then we can not record any equivalences for this
	 statement since we would need to represent the widening or
	 narrowing of RHS.  This fixes gcc.c-torture/execute/921016-1.c
	 and should not be necessary if GCC represented bitfields
	 properly.  */
      if (lhs_code == COMPONENT_REF
	  && DECL_BIT_FIELD (TREE_OPERAND (lhs, 1)))
	{
	  if (TREE_CONSTANT (rhs))
	    rhs = widen_bitfield (rhs, TREE_OPERAND (lhs, 1), lhs);
	  else
	    rhs = NULL;

	  /* If the value overflowed, then we can not use this equivalence.  */
	  if (rhs && ! is_gimple_min_invariant (rhs))
	    rhs = NULL;
	}

      if (rhs)
	{
	  /* Build a new statement with the RHS and LHS exchanged.  */
	  new = build (MODIFY_EXPR, TREE_TYPE (stmt), rhs, lhs);

	  create_ssa_artficial_load_stmt (&(ann->operands), new);

	  /* Finally enter the statement into the available expression
	     table.  */
	  lookup_avail_expr (new, true);
	}
    }
}

/* Replace *OP_P in STMT with any known equivalent value for *OP_P from
   CONST_AND_COPIES.  */

static bool
cprop_operand (tree stmt, use_operand_p op_p)
{
  bool may_have_exposed_new_symbols = false;
  tree val;
  tree op = USE_FROM_PTR (op_p);

  /* If the operand has a known constant value or it is known to be a
     copy of some other variable, use the value or copy stored in
     CONST_AND_COPIES.  */
  val = SSA_NAME_VALUE (op);
  if (val && TREE_CODE (val) != VALUE_HANDLE)
    {
      tree op_type, val_type;

      /* Do not change the base variable in the virtual operand
	 tables.  That would make it impossible to reconstruct
	 the renamed virtual operand if we later modify this
	 statement.  Also only allow the new value to be an SSA_NAME
	 for propagation into virtual operands.  */
      if (!is_gimple_reg (op)
	  && (get_virtual_var (val) != get_virtual_var (op)
	      || TREE_CODE (val) != SSA_NAME))
	return false;

      /* Do not replace hard register operands in asm statements.  */
      if (TREE_CODE (stmt) == ASM_EXPR
	  && !may_propagate_copy_into_asm (op))
	return false;

      /* Get the toplevel type of each operand.  */
      op_type = TREE_TYPE (op);
      val_type = TREE_TYPE (val);

      /* While both types are pointers, get the type of the object
	 pointed to.  */
      while (POINTER_TYPE_P (op_type) && POINTER_TYPE_P (val_type))
	{
	  op_type = TREE_TYPE (op_type);
	  val_type = TREE_TYPE (val_type);
	}

      /* Make sure underlying types match before propagating a constant by
	 converting the constant to the proper type.  Note that convert may
	 return a non-gimple expression, in which case we ignore this
	 propagation opportunity.  */
      if (TREE_CODE (val) != SSA_NAME)
	{
	  if (!lang_hooks.types_compatible_p (op_type, val_type))
	    {
	      val = fold_convert (TREE_TYPE (op), val);
	      if (!is_gimple_min_invariant (val))
		return false;
	    }
	}

      /* Certain operands are not allowed to be copy propagated due
	 to their interaction with exception handling and some GCC
	 extensions.  */
      else if (!may_propagate_copy (op, val))
	return false;
      
      /* Do not propagate copies if the propagated value is at a deeper loop
	 depth than the propagatee.  Otherwise, this may move loop variant
	 variables outside of their loops and prevent coalescing
	 opportunities.  If the value was loop invariant, it will be hoisted
	 by LICM and exposed for copy propagation.  */
      if (loop_depth_of_name (val) > loop_depth_of_name (op))
	return false;

      /* Dump details.  */
      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "  Replaced '");
	  print_generic_expr (dump_file, op, dump_flags);
	  fprintf (dump_file, "' with %s '",
		   (TREE_CODE (val) != SSA_NAME ? "constant" : "variable"));
	  print_generic_expr (dump_file, val, dump_flags);
	  fprintf (dump_file, "'\n");
	}

      /* If VAL is an ADDR_EXPR or a constant of pointer type, note
	 that we may have exposed a new symbol for SSA renaming.  */
      if (TREE_CODE (val) == ADDR_EXPR
	  || (POINTER_TYPE_P (TREE_TYPE (op))
	      && is_gimple_min_invariant (val)))
	may_have_exposed_new_symbols = true;

      propagate_value (op_p, val);

      /* And note that we modified this statement.  This is now
	 safe, even if we changed virtual operands since we will
	 rescan the statement and rewrite its operands again.  */
      modify_stmt (stmt);
    }
  return may_have_exposed_new_symbols;
}

/* CONST_AND_COPIES is a table which maps an SSA_NAME to the current
   known value for that SSA_NAME (or NULL if no value is known).  

   Propagate values from CONST_AND_COPIES into the uses, vuses and
   v_may_def_ops of STMT.  */

static bool
cprop_into_stmt (tree stmt)
{
  bool may_have_exposed_new_symbols = false;
  use_operand_p op_p;
  ssa_op_iter iter;
  tree rhs;

  FOR_EACH_SSA_USE_OPERAND (op_p, stmt, iter, SSA_OP_ALL_USES)
    {
      if (TREE_CODE (USE_FROM_PTR (op_p)) == SSA_NAME)
	may_have_exposed_new_symbols |= cprop_operand (stmt, op_p);
    }

  if (may_have_exposed_new_symbols)
    {
      rhs = get_rhs (stmt);
      if (rhs && TREE_CODE (rhs) == ADDR_EXPR)
	recompute_tree_invarant_for_addr_expr (rhs);
    }

  return may_have_exposed_new_symbols;
}


/* Optimize the statement pointed by iterator SI.
   
   We try to perform some simplistic global redundancy elimination and
   constant propagation:

   1- To detect global redundancy, we keep track of expressions that have
      been computed in this block and its dominators.  If we find that the
      same expression is computed more than once, we eliminate repeated
      computations by using the target of the first one.

   2- Constant values and copy assignments.  This is used to do very
      simplistic constant and copy propagation.  When a constant or copy
      assignment is found, we map the value on the RHS of the assignment to
      the variable in the LHS in the CONST_AND_COPIES table.  */

static void
optimize_stmt (struct dom_walk_data *walk_data, basic_block bb,
	       block_stmt_iterator si)
{
  stmt_ann_t ann;
  tree stmt;
  bool may_optimize_p;
  bool may_have_exposed_new_symbols = false;

  stmt = bsi_stmt (si);

  get_stmt_operands (stmt);
  ann = stmt_ann (stmt);
  opt_stats.num_stmts++;
  may_have_exposed_new_symbols = false;

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Optimizing statement ");
      print_generic_stmt (dump_file, stmt, TDF_SLIM);
    }

  /* Const/copy propagate into USES, VUSES and the RHS of V_MAY_DEFs.  */
  may_have_exposed_new_symbols = cprop_into_stmt (stmt);

  /* If the statement has been modified with constant replacements,
     fold its RHS before checking for redundant computations.  */
  if (ann->modified)
    {
      /* Try to fold the statement making sure that STMT is kept
	 up to date.  */
      if (fold_stmt (bsi_stmt_ptr (si)))
	{
	  stmt = bsi_stmt (si);
	  ann = stmt_ann (stmt);

	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "  Folded to: ");
	      print_generic_stmt (dump_file, stmt, TDF_SLIM);
	    }
	}

      /* Constant/copy propagation above may change the set of 
	 virtual operands associated with this statement.  Folding
	 may remove the need for some virtual operands.

	 Indicate we will need to rescan and rewrite the statement.  */
      may_have_exposed_new_symbols = true;
    }

  /* Check for redundant computations.  Do this optimization only
     for assignments that have no volatile ops and conditionals.  */
  may_optimize_p = (!ann->has_volatile_ops
		    && ((TREE_CODE (stmt) == RETURN_EXPR
			 && TREE_OPERAND (stmt, 0)
			 && TREE_CODE (TREE_OPERAND (stmt, 0)) == MODIFY_EXPR
			 && ! (TREE_SIDE_EFFECTS
			       (TREE_OPERAND (TREE_OPERAND (stmt, 0), 1))))
			|| (TREE_CODE (stmt) == MODIFY_EXPR
			    && ! TREE_SIDE_EFFECTS (TREE_OPERAND (stmt, 1)))
			|| TREE_CODE (stmt) == COND_EXPR
			|| TREE_CODE (stmt) == SWITCH_EXPR));

  if (may_optimize_p)
    may_have_exposed_new_symbols
      |= eliminate_redundant_computations (walk_data, stmt, ann);

  /* Record any additional equivalences created by this statement.  */
  if (TREE_CODE (stmt) == MODIFY_EXPR)
    record_equivalences_from_stmt (stmt,
				   may_optimize_p,
				   ann);

  register_definitions_for_stmt (stmt);

  /* If STMT is a COND_EXPR and it was modified, then we may know
     where it goes.  If that is the case, then mark the CFG as altered.

     This will cause us to later call remove_unreachable_blocks and
     cleanup_tree_cfg when it is safe to do so.  It is not safe to 
     clean things up here since removal of edges and such can trigger
     the removal of PHI nodes, which in turn can release SSA_NAMEs to
     the manager.

     That's all fine and good, except that once SSA_NAMEs are released
     to the manager, we must not call create_ssa_name until all references
     to released SSA_NAMEs have been eliminated.

     All references to the deleted SSA_NAMEs can not be eliminated until
     we remove unreachable blocks.

     We can not remove unreachable blocks until after we have completed
     any queued jump threading.

     We can not complete any queued jump threads until we have taken
     appropriate variables out of SSA form.  Taking variables out of
     SSA form can call create_ssa_name and thus we lose.

     Ultimately I suspect we're going to need to change the interface
     into the SSA_NAME manager.  */

  if (ann->modified)
    {
      tree val = NULL;

      if (TREE_CODE (stmt) == COND_EXPR)
	val = COND_EXPR_COND (stmt);
      else if (TREE_CODE (stmt) == SWITCH_EXPR)
	val = SWITCH_COND (stmt);

      if (val && TREE_CODE (val) == INTEGER_CST && find_taken_edge (bb, val))
	cfg_altered = true;

      /* If we simplified a statement in such a way as to be shown that it
	 cannot trap, update the eh information and the cfg to match.  */
      if (maybe_clean_eh_stmt (stmt))
	{
	  bitmap_set_bit (need_eh_cleanup, bb->index);
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file, "  Flagged to clear EH edges.\n");
	}
    }

  if (may_have_exposed_new_symbols)
    VEC_safe_push (tree_on_heap, stmts_to_rescan, bsi_stmt (si));
}

/* Replace the RHS of STMT with NEW_RHS.  If RHS can be found in the
   available expression hashtable, then return the LHS from the hash
   table.

   If INSERT is true, then we also update the available expression
   hash table to account for the changes made to STMT.  */

static tree
update_rhs_and_lookup_avail_expr (tree stmt, tree new_rhs, bool insert)
{
  tree cached_lhs = NULL;

  /* Remove the old entry from the hash table.  */
  if (insert)
    {
      struct expr_hash_elt element;

      initialize_hash_element (stmt, NULL, &element);
      htab_remove_elt_with_hash (avail_exprs, &element, element.hash);
    }

  /* Now update the RHS of the assignment.  */
  TREE_OPERAND (stmt, 1) = new_rhs;

  /* Now lookup the updated statement in the hash table.  */
  cached_lhs = lookup_avail_expr (stmt, insert);

  /* We have now called lookup_avail_expr twice with two different
     versions of this same statement, once in optimize_stmt, once here.

     We know the call in optimize_stmt did not find an existing entry
     in the hash table, so a new entry was created.  At the same time
     this statement was pushed onto the AVAIL_EXPRS_STACK vector. 

     If this call failed to find an existing entry on the hash table,
     then the new version of this statement was entered into the
     hash table.  And this statement was pushed onto BLOCK_AVAIL_EXPR
     for the second time.  So there are two copies on BLOCK_AVAIL_EXPRs

     If this call succeeded, we still have one copy of this statement
     on the BLOCK_AVAIL_EXPRs vector.

     For both cases, we need to pop the most recent entry off the
     BLOCK_AVAIL_EXPRs vector.  For the case where we never found this
     statement in the hash tables, that will leave precisely one
     copy of this statement on BLOCK_AVAIL_EXPRs.  For the case where
     we found a copy of this statement in the second hash table lookup
     we want _no_ copies of this statement in BLOCK_AVAIL_EXPRs.  */
  if (insert)
    VEC_pop (tree_on_heap, avail_exprs_stack);

  /* And make sure we record the fact that we modified this
     statement.  */
  modify_stmt (stmt);

  return cached_lhs;
}

/* Search for an existing instance of STMT in the AVAIL_EXPRS table.  If
   found, return its LHS. Otherwise insert STMT in the table and return
   NULL_TREE.

   Also, when an expression is first inserted in the AVAIL_EXPRS table, it
   is also added to the stack pointed by BLOCK_AVAIL_EXPRS_P, so that they
   can be removed when we finish processing this block and its children.

   NOTE: This function assumes that STMT is a MODIFY_EXPR node that
   contains no CALL_EXPR on its RHS and makes no volatile nor
   aliased references.  */

static tree
lookup_avail_expr (tree stmt, bool insert)
{
  void **slot;
  tree lhs;
  tree temp;
  struct expr_hash_elt *element = xmalloc (sizeof (struct expr_hash_elt));

  lhs = TREE_CODE (stmt) == MODIFY_EXPR ? TREE_OPERAND (stmt, 0) : NULL;

  initialize_hash_element (stmt, lhs, element);

  /* Don't bother remembering constant assignments and copy operations.
     Constants and copy operations are handled by the constant/copy propagator
     in optimize_stmt.  */
  if (TREE_CODE (element->rhs) == SSA_NAME
      || is_gimple_min_invariant (element->rhs))
    {
      free (element);
      return NULL_TREE;
    }

  /* If this is an equality test against zero, see if we have recorded a
     nonzero value for the variable in question.  */
  if ((TREE_CODE (element->rhs) == EQ_EXPR
       || TREE_CODE  (element->rhs) == NE_EXPR)
      && TREE_CODE (TREE_OPERAND (element->rhs, 0)) == SSA_NAME
      && integer_zerop (TREE_OPERAND (element->rhs, 1)))
    {
      int indx = SSA_NAME_VERSION (TREE_OPERAND (element->rhs, 0));

      if (bitmap_bit_p (nonzero_vars, indx))
	{
	  tree t = element->rhs;
	  free (element);

	  if (TREE_CODE (t) == EQ_EXPR)
	    return boolean_false_node;
	  else
	    return boolean_true_node;
	}
    }

  /* Finally try to find the expression in the main expression hash table.  */
  slot = htab_find_slot_with_hash (avail_exprs, element, element->hash,
				   (insert ? INSERT : NO_INSERT));
  if (slot == NULL)
    {
      free (element);
      return NULL_TREE;
    }

  if (*slot == NULL)
    {
      *slot = (void *) element;
      VEC_safe_push (tree_on_heap, avail_exprs_stack,
		     stmt ? stmt : element->rhs);
      return NULL_TREE;
    }

  /* Extract the LHS of the assignment so that it can be used as the current
     definition of another variable.  */
  lhs = ((struct expr_hash_elt *)*slot)->lhs;

  /* See if the LHS appears in the CONST_AND_COPIES table.  If it does, then
     use the value from the const_and_copies table.  */
  if (TREE_CODE (lhs) == SSA_NAME)
    {
      temp = SSA_NAME_VALUE (lhs);
      if (temp && TREE_CODE (temp) != VALUE_HANDLE)
	lhs = temp;
    }

  free (element);
  return lhs;
}

/* Given a condition COND, record into HI_P, LO_P and INVERTED_P the
   range of values that result in the conditional having a true value.

   Return true if we are successful in extracting a range from COND and
   false if we are unsuccessful.  */

static bool
extract_range_from_cond (tree cond, tree *hi_p, tree *lo_p, int *inverted_p)
{
  tree op1 = TREE_OPERAND (cond, 1);
  tree high, low, type;
  int inverted;

  type = TREE_TYPE (op1);

  /* Experiments have shown that it's rarely, if ever useful to
     record ranges for enumerations.  Presumably this is due to
     the fact that they're rarely used directly.  They are typically
     cast into an integer type and used that way.  */
  if (TREE_CODE (type) != INTEGER_TYPE
      /* We don't know how to deal with types with variable bounds.  */
      || TREE_CODE (TYPE_MIN_VALUE (type)) != INTEGER_CST
      || TREE_CODE (TYPE_MAX_VALUE (type)) != INTEGER_CST)
    return 0;

  switch (TREE_CODE (cond))
    {
    case EQ_EXPR:
      high = low = op1;
      inverted = 0;
      break;

    case NE_EXPR:
      high = low = op1;
      inverted = 1;
      break;

    case GE_EXPR:
      low = op1;
      high = TYPE_MAX_VALUE (type);
      inverted = 0;
      break;

    case GT_EXPR:
      high = TYPE_MAX_VALUE (type);
      if (!tree_int_cst_lt (op1, high))
	return 0;
      low = int_const_binop (PLUS_EXPR, op1, integer_one_node, 1);
      inverted = 0;
      break;

    case LE_EXPR:
      high = op1;
      low = TYPE_MIN_VALUE (type);
      inverted = 0;
      break;

    case LT_EXPR:
      low = TYPE_MIN_VALUE (type);
      if (!tree_int_cst_lt (low, op1))
	return 0;
      high = int_const_binop (MINUS_EXPR, op1, integer_one_node, 1);
      inverted = 0;
      break;

    default:
      return 0;
    }

  *hi_p = high;
  *lo_p = low;
  *inverted_p = inverted;
  return 1;
}

/* Record a range created by COND for basic block BB.  */

static void
record_range (tree cond, basic_block bb)
{
  enum tree_code code = TREE_CODE (cond);

  /* We explicitly ignore NE_EXPRs and all the unordered comparisons.
     They rarely allow for meaningful range optimizations and significantly
     complicate the implementation.  */
  if ((code == LT_EXPR || code == LE_EXPR || code == GT_EXPR
       || code == GE_EXPR || code == EQ_EXPR)
      && TREE_CODE (TREE_TYPE (TREE_OPERAND (cond, 1))) == INTEGER_TYPE)
    {
      struct vrp_hash_elt *vrp_hash_elt;
      struct vrp_element *element;
      varray_type *vrp_records_p;
      void **slot;


      vrp_hash_elt = xmalloc (sizeof (struct vrp_hash_elt));
      vrp_hash_elt->var = TREE_OPERAND (cond, 0);
      vrp_hash_elt->records = NULL;
      slot = htab_find_slot (vrp_data, vrp_hash_elt, INSERT);

      if (*slot == NULL)
	*slot = (void *) vrp_hash_elt;
      else
	free (vrp_hash_elt);

      vrp_hash_elt = (struct vrp_hash_elt *) *slot;
      vrp_records_p = &vrp_hash_elt->records;

      element = ggc_alloc (sizeof (struct vrp_element));
      element->low = NULL;
      element->high = NULL;
      element->cond = cond;
      element->bb = bb;

      if (*vrp_records_p == NULL)
	VARRAY_GENERIC_PTR_INIT (*vrp_records_p, 2, "vrp records");
      
      VARRAY_PUSH_GENERIC_PTR (*vrp_records_p, element);
      VEC_safe_push (tree_on_heap, vrp_variables_stack, TREE_OPERAND (cond, 0));
    }
}

/* Hashing and equality functions for VRP_DATA.

   Since this hash table is addressed by SSA_NAMEs, we can hash on
   their version number and equality can be determined with a 
   pointer comparison.  */

static hashval_t
vrp_hash (const void *p)
{
  tree var = ((struct vrp_hash_elt *)p)->var;

  return SSA_NAME_VERSION (var);
}

static int
vrp_eq (const void *p1, const void *p2)
{
  tree var1 = ((struct vrp_hash_elt *)p1)->var;
  tree var2 = ((struct vrp_hash_elt *)p2)->var;

  return var1 == var2;
}

/* Hashing and equality functions for AVAIL_EXPRS.  The table stores
   MODIFY_EXPR statements.  We compute a value number for expressions using
   the code of the expression and the SSA numbers of its operands.  */

static hashval_t
avail_expr_hash (const void *p)
{
  stmt_ann_t ann = ((struct expr_hash_elt *)p)->ann;
  tree rhs = ((struct expr_hash_elt *)p)->rhs;
  hashval_t val = 0;
  size_t i;
  vuse_optype vuses;

  /* iterative_hash_expr knows how to deal with any expression and
     deals with commutative operators as well, so just use it instead
     of duplicating such complexities here.  */
  val = iterative_hash_expr (rhs, val);

  /* If the hash table entry is not associated with a statement, then we
     can just hash the expression and not worry about virtual operands
     and such.  */
  if (!ann)
    return val;

  /* Add the SSA version numbers of every vuse operand.  This is important
     because compound variables like arrays are not renamed in the
     operands.  Rather, the rename is done on the virtual variable
     representing all the elements of the array.  */
  vuses = VUSE_OPS (ann);
  for (i = 0; i < NUM_VUSES (vuses); i++)
    val = iterative_hash_expr (VUSE_OP (vuses, i), val);

  return val;
}

static hashval_t
real_avail_expr_hash (const void *p)
{
  return ((const struct expr_hash_elt *)p)->hash;
}

static int
avail_expr_eq (const void *p1, const void *p2)
{
  stmt_ann_t ann1 = ((struct expr_hash_elt *)p1)->ann;
  tree rhs1 = ((struct expr_hash_elt *)p1)->rhs;
  stmt_ann_t ann2 = ((struct expr_hash_elt *)p2)->ann;
  tree rhs2 = ((struct expr_hash_elt *)p2)->rhs;

  /* If they are the same physical expression, return true.  */
  if (rhs1 == rhs2 && ann1 == ann2)
    return true;

  /* If their codes are not equal, then quit now.  */
  if (TREE_CODE (rhs1) != TREE_CODE (rhs2))
    return false;

  /* In case of a collision, both RHS have to be identical and have the
     same VUSE operands.  */
  if ((TREE_TYPE (rhs1) == TREE_TYPE (rhs2)
       || lang_hooks.types_compatible_p (TREE_TYPE (rhs1), TREE_TYPE (rhs2)))
      && operand_equal_p (rhs1, rhs2, OEP_PURE_SAME))
    {
      vuse_optype ops1 = NULL;
      vuse_optype ops2 = NULL;
      size_t num_ops1 = 0;
      size_t num_ops2 = 0;
      size_t i;

      if (ann1)
	{
	  ops1 = VUSE_OPS (ann1);
	  num_ops1 = NUM_VUSES (ops1);
	}

      if (ann2)
	{
	  ops2 = VUSE_OPS (ann2);
	  num_ops2 = NUM_VUSES (ops2);
	}

      /* If the number of virtual uses is different, then we consider
	 them not equal.  */
      if (num_ops1 != num_ops2)
	return false;

      for (i = 0; i < num_ops1; i++)
	if (VUSE_OP (ops1, i) != VUSE_OP (ops2, i))
	  return false;

      gcc_assert (((struct expr_hash_elt *)p1)->hash
		  == ((struct expr_hash_elt *)p2)->hash);
      return true;
    }

  return false;
}

/* Given STMT and a pointer to the block local definitions BLOCK_DEFS_P,
   register register all objects set by this statement into BLOCK_DEFS_P
   and CURRDEFS.  */

static void
register_definitions_for_stmt (tree stmt)
{
  tree def;
  ssa_op_iter iter;

  FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
    {

      /* FIXME: We shouldn't be registering new defs if the variable
	 doesn't need to be renamed.  */
      register_new_def (def, &block_defs_stack);
    }
}

