/* Copy propagation and SSA_NAME replacement support routines.
   Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.

This file is part of GCC.

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

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

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

#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 "expr.h"
#include "function.h"
#include "diagnostic.h"
#include "timevar.h"
#include "tree-dump.h"
#include "tree-flow.h"
#include "tree-pass.h"
#include "tree-ssa-propagate.h"
#include "langhooks.h"

/* This file implements the copy propagation pass and provides a
   handful of interfaces for performing const/copy propagation and
   simple expression replacement which keep variable annotations
   up-to-date.

   We require that for any copy operation where the RHS and LHS have
   a non-null memory tag the memory tag be the same.   It is OK
   for one or both of the memory tags to be NULL.

   We also require tracking if a variable is dereferenced in a load or
   store operation.

   We enforce these requirements by having all copy propagation and
   replacements of one SSA_NAME with a different SSA_NAME to use the
   APIs defined in this file.  */

/* Return true if we may propagate ORIG into DEST, false otherwise.  */

bool
may_propagate_copy (tree dest, tree orig)
{
  tree type_d = TREE_TYPE (dest);
  tree type_o = TREE_TYPE (orig);

  /* If ORIG flows in from an abnormal edge, it cannot be propagated.  */
  if (TREE_CODE (orig) == SSA_NAME
      && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig))
    return false;

  /* If DEST is an SSA_NAME that flows from an abnormal edge, then it
     cannot be replaced.  */
  if (TREE_CODE (dest) == SSA_NAME
      && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (dest))
    return false;

  /* For memory partitions, copies are OK as long as the memory symbol
     belongs to the partition.  */
  if (TREE_CODE (dest) == SSA_NAME
      && TREE_CODE (SSA_NAME_VAR (dest)) == MEMORY_PARTITION_TAG)
    return (TREE_CODE (orig) == SSA_NAME
            && !is_gimple_reg (orig)
	    && (SSA_NAME_VAR (dest) == SSA_NAME_VAR (orig)
	        || bitmap_bit_p (MPT_SYMBOLS (SSA_NAME_VAR (dest)),
	                         DECL_UID (SSA_NAME_VAR (orig)))));

  if (TREE_CODE (orig) == SSA_NAME
      && TREE_CODE (SSA_NAME_VAR (orig)) == MEMORY_PARTITION_TAG)
    return (TREE_CODE (dest) == SSA_NAME
            && !is_gimple_reg (dest)
	    && (SSA_NAME_VAR (dest) == SSA_NAME_VAR (orig)
                || bitmap_bit_p (MPT_SYMBOLS (SSA_NAME_VAR (orig)),
	                         DECL_UID (SSA_NAME_VAR (dest)))));
  
  /* Do not copy between types for which we *do* need a conversion.  */
  if (!useless_type_conversion_p (type_d, type_o))
    return false;

  /* FIXME.  GIMPLE is allowing pointer assignments and comparisons of
     pointers that have different alias sets.  This means that these
     pointers will have different memory tags associated to them.

     If we allow copy propagation in these cases, statements de-referencing
     the new pointer will now have a reference to a different memory tag
     with potentially incorrect SSA information.

     This was showing up in libjava/java/util/zip/ZipFile.java with code
     like:

     	struct java.io.BufferedInputStream *T.660;
	struct java.io.BufferedInputStream *T.647;
	struct java.io.InputStream *is;
	struct java.io.InputStream *is.662;
	[ ... ]
	T.660 = T.647;
	is = T.660;	<-- This ought to be type-casted
	is.662 = is;

     Also, f/name.c exposed a similar problem with a COND_EXPR predicate
     that was causing DOM to generate and equivalence with two pointers of
     alias-incompatible types:

     	struct _ffename_space *n;
	struct _ffename *ns;
	[ ... ]
	if (n == ns)
	  goto lab;
	...
	lab:
	return n;

     I think that GIMPLE should emit the appropriate type-casts.  For the
     time being, blocking copy-propagation in these cases is the safe thing
     to do.  */
  if (TREE_CODE (dest) == SSA_NAME
      && TREE_CODE (orig) == SSA_NAME
      && POINTER_TYPE_P (type_d)
      && POINTER_TYPE_P (type_o))
    {
      tree mt_dest = symbol_mem_tag (SSA_NAME_VAR (dest));
      tree mt_orig = symbol_mem_tag (SSA_NAME_VAR (orig));
      if (mt_dest && mt_orig && mt_dest != mt_orig)
	return false;
      else if (get_alias_set (TREE_TYPE (type_d)) != 
	       get_alias_set (TREE_TYPE (type_o)))
	return false;
      else if (!MTAG_P (SSA_NAME_VAR (dest))
	       && !MTAG_P (SSA_NAME_VAR (orig))
	       && (DECL_NO_TBAA_P (SSA_NAME_VAR (dest))
		   != DECL_NO_TBAA_P (SSA_NAME_VAR (orig))))
	return false;

      /* Also verify flow-sensitive information is compatible.  */
      if (SSA_NAME_PTR_INFO (orig) && SSA_NAME_PTR_INFO (dest))
	{
	  struct ptr_info_def *orig_ptr_info = SSA_NAME_PTR_INFO (orig);
	  struct ptr_info_def *dest_ptr_info = SSA_NAME_PTR_INFO (dest);

	  if (orig_ptr_info->name_mem_tag
	      && dest_ptr_info->name_mem_tag
	      && orig_ptr_info->pt_vars
	      && dest_ptr_info->pt_vars
	      && !bitmap_intersect_p (dest_ptr_info->pt_vars,
				      orig_ptr_info->pt_vars))
	    return false;
	}
    }

  /* If the destination is a SSA_NAME for a virtual operand, then we have
     some special cases to handle.  */
  if (TREE_CODE (dest) == SSA_NAME && !is_gimple_reg (dest))
    {
      /* If both operands are SSA_NAMEs referring to virtual operands, then
	 we can always propagate.  */
      if (TREE_CODE (orig) == SSA_NAME
	  && !is_gimple_reg (orig))
	return true;

      /* We have a "copy" from something like a constant into a virtual
	 operand.  Reject these.  */
      return false;
    }

  /* Anything else is OK.  */
  return true;
}

/* Like may_propagate_copy, but use as the destination expression
   the principal expression (typically, the RHS) contained in
   statement DEST.  This is more efficient when working with the
   gimple tuples representation.  */

bool
may_propagate_copy_into_stmt (gimple dest, tree orig)
{
  tree type_d;
  tree type_o;

  /* If the statement is a switch or a single-rhs assignment,
     then the expression to be replaced by the propagation may
     be an SSA_NAME.  Fortunately, there is an explicit tree
     for the expression, so we delegate to may_propagate_copy.  */

  if (gimple_assign_single_p (dest))
    return may_propagate_copy (gimple_assign_rhs1 (dest), orig);
  else if (gimple_code (dest) == GIMPLE_SWITCH)
    return may_propagate_copy (gimple_switch_index (dest), orig);

  /* In other cases, the expression is not materialized, so there
     is no destination to pass to may_propagate_copy.  On the other
     hand, the expression cannot be an SSA_NAME, so the analysis
     is much simpler.  */

  if (TREE_CODE (orig) == SSA_NAME
      && (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig)
          ||  TREE_CODE (SSA_NAME_VAR (orig)) == MEMORY_PARTITION_TAG))
    return false;

  if (is_gimple_assign (dest))
    type_d = TREE_TYPE (gimple_assign_lhs (dest));
  else if (gimple_code (dest) == GIMPLE_COND)
    type_d = boolean_type_node;
  else if (is_gimple_call (dest)
           && gimple_call_lhs (dest) != NULL_TREE)
    type_d = TREE_TYPE (gimple_call_lhs (dest));
  else
    gcc_unreachable ();

  type_o = TREE_TYPE (orig);

  if (!useless_type_conversion_p (type_d, type_o))
    return false;

  return true;
}

/* Similarly, but we know that we're propagating into an ASM_EXPR.  */

bool
may_propagate_copy_into_asm (tree dest)
{
  /* Hard register operands of asms are special.  Do not bypass.  */
  return !(TREE_CODE (dest) == SSA_NAME
	   && TREE_CODE (SSA_NAME_VAR (dest)) == VAR_DECL
	   && DECL_HARD_REGISTER (SSA_NAME_VAR (dest)));
}


/* Given two SSA_NAMEs pointers ORIG and NEW such that we are copy
   propagating NEW into ORIG, consolidate aliasing information so that
   they both share the same memory tags.  */

void
merge_alias_info (tree orig_name, tree new_name)
{
  tree new_sym = SSA_NAME_VAR (new_name);
  tree orig_sym = SSA_NAME_VAR (orig_name);
  var_ann_t new_ann = var_ann (new_sym);
  var_ann_t orig_ann = var_ann (orig_sym);

  /* No merging necessary when memory partitions are involved.  */
  if (factoring_name_p (new_name))
    {
      gcc_assert (!is_gimple_reg (orig_sym));
      return;
    }
  else if (factoring_name_p (orig_name))
    {
      gcc_assert (!is_gimple_reg (new_sym));
      return;
    }

  gcc_assert (POINTER_TYPE_P (TREE_TYPE (orig_name))
	      && POINTER_TYPE_P (TREE_TYPE (new_name)));

#if defined ENABLE_CHECKING
  gcc_assert (useless_type_conversion_p (TREE_TYPE (orig_name),
					TREE_TYPE (new_name)));

  /* Check that flow-sensitive information is compatible.  Notice that
     we may not merge flow-sensitive information here.  This function
     is called when propagating equivalences dictated by the IL, like
     a copy operation P_i = Q_j, and from equivalences dictated by
     control-flow, like if (P_i == Q_j).
     
     In the former case, P_i and Q_j are equivalent in every block
     dominated by the assignment, so their flow-sensitive information
     is always the same.  However, in the latter case, the pointers
     P_i and Q_j are only equivalent in one of the sub-graphs out of
     the predicate, so their flow-sensitive information is not the
     same in every block dominated by the predicate.

     Since we cannot distinguish one case from another in this
     function, we can only make sure that if P_i and Q_j have
     flow-sensitive information, they should be compatible.

     As callers of merge_alias_info are supposed to call may_propagate_copy
     first, the following check is redundant.  Thus, only do it if checking
     is enabled.  */
  if (SSA_NAME_PTR_INFO (orig_name) && SSA_NAME_PTR_INFO (new_name))
    {
      struct ptr_info_def *orig_ptr_info = SSA_NAME_PTR_INFO (orig_name);
      struct ptr_info_def *new_ptr_info = SSA_NAME_PTR_INFO (new_name);

      /* Note that pointer NEW and ORIG may actually have different
	 pointed-to variables (e.g., PR 18291 represented in
	 testsuite/gcc.c-torture/compile/pr18291.c).  However, since
	 NEW is being copy-propagated into ORIG, it must always be
	 true that the pointed-to set for pointer NEW is the same, or
	 a subset, of the pointed-to set for pointer ORIG.  If this
	 isn't the case, we shouldn't have been able to do the
	 propagation of NEW into ORIG.  */
      if (orig_ptr_info->name_mem_tag
	  && new_ptr_info->name_mem_tag
	  && orig_ptr_info->pt_vars
	  && new_ptr_info->pt_vars)
	gcc_assert (bitmap_intersect_p (new_ptr_info->pt_vars,
					orig_ptr_info->pt_vars));
    }
#endif

  /* Synchronize the symbol tags.  If both pointers had a tag and they
     are different, then something has gone wrong.  Symbol tags can
     always be merged because they are flow insensitive, all the SSA
     names of the same base DECL share the same symbol tag.  */
  if (new_ann->symbol_mem_tag == NULL_TREE)
    new_ann->symbol_mem_tag = orig_ann->symbol_mem_tag;
  else if (orig_ann->symbol_mem_tag == NULL_TREE)
    orig_ann->symbol_mem_tag = new_ann->symbol_mem_tag;
  else
    gcc_assert (new_ann->symbol_mem_tag == orig_ann->symbol_mem_tag);

  /* Copy flow-sensitive alias information in case that NEW_NAME
     didn't get a NMT but was set to pt_anything for optimization
     purposes.  In case ORIG_NAME has a NMT we can safely use its
     flow-sensitive alias information as a conservative estimate.  */
  if (SSA_NAME_PTR_INFO (orig_name)
      && SSA_NAME_PTR_INFO (orig_name)->name_mem_tag
      && (!SSA_NAME_PTR_INFO (new_name)
	  || !SSA_NAME_PTR_INFO (new_name)->name_mem_tag))
    {
      struct ptr_info_def *orig_ptr_info = SSA_NAME_PTR_INFO (orig_name);
      struct ptr_info_def *new_ptr_info = get_ptr_info (new_name);
      memcpy (new_ptr_info, orig_ptr_info, sizeof (struct ptr_info_def));
    }
}


/* Common code for propagate_value and replace_exp.

   Replace use operand OP_P with VAL.  FOR_PROPAGATION indicates if the
   replacement is done to propagate a value or not.  */

static void
replace_exp_1 (use_operand_p op_p, tree val,
    	       bool for_propagation ATTRIBUTE_UNUSED)
{
  tree op = USE_FROM_PTR (op_p);

#if defined ENABLE_CHECKING
  gcc_assert (!(for_propagation
		&& TREE_CODE (op) == SSA_NAME
		&& TREE_CODE (val) == SSA_NAME
		&& !may_propagate_copy (op, val)));
#endif

  if (TREE_CODE (val) == SSA_NAME)
    {
      if (TREE_CODE (op) == SSA_NAME && POINTER_TYPE_P (TREE_TYPE (op)))
	merge_alias_info (op, val);
      SET_USE (op_p, val);
    }
  else
    SET_USE (op_p, unsave_expr_now (val));
}


/* Propagate the value VAL (assumed to be a constant or another SSA_NAME)
   into the operand pointed to by OP_P.

   Use this version for const/copy propagation as it will perform additional
   checks to ensure validity of the const/copy propagation.  */

void
propagate_value (use_operand_p op_p, tree val)
{
  replace_exp_1 (op_p, val, true);
}

/* Replace *OP_P with value VAL (assumed to be a constant or another SSA_NAME).

   Use this version when not const/copy propagating values.  For example,
   PRE uses this version when building expressions as they would appear
   in specific blocks taking into account actions of PHI nodes.  */

void
replace_exp (use_operand_p op_p, tree val)
{
  replace_exp_1 (op_p, val, false);
}


/* Propagate the value VAL (assumed to be a constant or another SSA_NAME)
   into the tree pointed to by OP_P.

   Use this version for const/copy propagation when SSA operands are not
   available.  It will perform the additional checks to ensure validity of
   the const/copy propagation, but will not update any operand information.
   Be sure to mark the stmt as modified.  */

void
propagate_tree_value (tree *op_p, tree val)
{
#if defined ENABLE_CHECKING
  gcc_assert (!(TREE_CODE (val) == SSA_NAME
                && *op_p
		&& TREE_CODE (*op_p) == SSA_NAME
		&& !may_propagate_copy (*op_p, val)));
#endif

  if (TREE_CODE (val) == SSA_NAME)
    {
      if (*op_p && TREE_CODE (*op_p) == SSA_NAME && POINTER_TYPE_P (TREE_TYPE (*op_p)))
	merge_alias_info (*op_p, val);
      *op_p = val;
    }
  else
    *op_p = unsave_expr_now (val);
}


/* Like propagate_tree_value, but use as the operand to replace
   the principal expression (typically, the RHS) contained in the
   statement referenced by iterator GSI.  Note that it is not
   always possible to update the statement in-place, so a new
   statement may be created to replace the original.  */

void
propagate_tree_value_into_stmt (gimple_stmt_iterator *gsi, tree val)
{
  gimple stmt = gsi_stmt (*gsi);

  if (is_gimple_assign (stmt))
    {
      tree expr = NULL_TREE;
      if (gimple_assign_single_p (stmt))
        expr = gimple_assign_rhs1 (stmt);
      propagate_tree_value (&expr, val);
      gimple_assign_set_rhs_from_tree (gsi, expr);
      stmt = gsi_stmt (*gsi);
    }
  else if (gimple_code (stmt) == GIMPLE_COND)
    {
      tree lhs = NULL_TREE;
      tree rhs = fold_convert (TREE_TYPE (val), integer_zero_node);
      propagate_tree_value (&lhs, val);
      gimple_cond_set_code (stmt, NE_EXPR);
      gimple_cond_set_lhs (stmt, lhs);
      gimple_cond_set_rhs (stmt, rhs);
    }
  else if (is_gimple_call (stmt)
           && gimple_call_lhs (stmt) != NULL_TREE)
    {
      gimple new_stmt;

      tree expr = NULL_TREE;
      propagate_tree_value (&expr, val);
      new_stmt  = gimple_build_assign (gimple_call_lhs (stmt), expr);
      copy_virtual_operands (new_stmt, stmt);
      move_ssa_defining_stmt_for_defs (new_stmt, stmt);
      gsi_replace (gsi, new_stmt, false);
    }
  else if (gimple_code (stmt) == GIMPLE_SWITCH)
    propagate_tree_value (gimple_switch_index_ptr (stmt), val);
  else
    gcc_unreachable ();
}

/*---------------------------------------------------------------------------
				Copy propagation
---------------------------------------------------------------------------*/
/* During propagation, we keep chains of variables that are copies of
   one another.  If variable X_i is a copy of X_j and X_j is a copy of
   X_k, COPY_OF will contain:

   	COPY_OF[i].VALUE = X_j
	COPY_OF[j].VALUE = X_k
	COPY_OF[k].VALUE = X_k

   After propagation, the copy-of value for each variable X_i is
   converted into the final value by walking the copy-of chains and
   updating COPY_OF[i].VALUE to be the last element of the chain.  */
static prop_value_t *copy_of;

/* Used in set_copy_of_val to determine if the last link of a copy-of
   chain has changed.  */
static tree *cached_last_copy_of;


/* Return true if this statement may generate a useful copy.  */

static bool
stmt_may_generate_copy (gimple stmt)
{
  if (gimple_code (stmt) == GIMPLE_PHI)
    return !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_phi_result (stmt));

  if (gimple_code (stmt) != GIMPLE_ASSIGN)
    return false;

  /* If the statement has volatile operands, it won't generate a
     useful copy.  */
  if (gimple_has_volatile_ops (stmt))
    return false;

  /* Statements with loads and/or stores will never generate a useful copy.  */
  if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
    return false;

  /* Otherwise, the only statements that generate useful copies are
     assignments whose RHS is just an SSA name that doesn't flow
     through abnormal edges.  */
  return (gimple_assign_rhs_code (stmt) == SSA_NAME
	  && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (stmt)));
}


/* Return the copy-of value for VAR.  */

static inline prop_value_t *
get_copy_of_val (tree var)
{
  prop_value_t *val = &copy_of[SSA_NAME_VERSION (var)];

  if (val->value == NULL_TREE
      && !stmt_may_generate_copy (SSA_NAME_DEF_STMT (var)))
    {
      /* If the variable will never generate a useful copy relation,
	 make it its own copy.  */
      val->value = var;
    }

  return val;
}


/* Return last link in the copy-of chain for VAR.  */

static tree
get_last_copy_of (tree var)
{
  tree last;
  int i;

  /* Traverse COPY_OF starting at VAR until we get to the last
     link in the chain.  Since it is possible to have cycles in PHI
     nodes, the copy-of chain may also contain cycles.
     
     To avoid infinite loops and to avoid traversing lengthy copy-of
     chains, we artificially limit the maximum number of chains we are
     willing to traverse.

     The value 5 was taken from a compiler and runtime library
     bootstrap and a mixture of C and C++ code from various sources.
     More than 82% of all copy-of chains were shorter than 5 links.  */
#define LIMIT	5

  last = var;
  for (i = 0; i < LIMIT; i++)
    {
      tree copy = copy_of[SSA_NAME_VERSION (last)].value;
      if (copy == NULL_TREE || copy == last)
	break;
      last = copy;
    }

  /* If we have reached the limit, then we are either in a copy-of
     cycle or the copy-of chain is too long.  In this case, just
     return VAR so that it is not considered a copy of anything.  */
  return (i < LIMIT ? last : var);
}


/* Set FIRST to be the first variable in the copy-of chain for DEST.
   If DEST's copy-of value or its copy-of chain has changed, return
   true.

   MEM_REF is the memory reference where FIRST is stored.  This is
   used when DEST is a non-register and we are copy propagating loads
   and stores.  */

static inline bool
set_copy_of_val (tree dest, tree first)
{
  unsigned int dest_ver = SSA_NAME_VERSION (dest);
  tree old_first, old_last, new_last;
  
  /* Set FIRST to be the first link in COPY_OF[DEST].  If that
     changed, return true.  */
  old_first = copy_of[dest_ver].value;
  copy_of[dest_ver].value = first;

  if (old_first != first)
    return true;

  /* If FIRST and OLD_FIRST are the same, we need to check whether the
     copy-of chain starting at FIRST ends in a different variable.  If
     the copy-of chain starting at FIRST ends up in a different
     variable than the last cached value we had for DEST, then return
     true because DEST is now a copy of a different variable.

     This test is necessary because even though the first link in the
     copy-of chain may not have changed, if any of the variables in
     the copy-of chain changed its final value, DEST will now be the
     copy of a different variable, so we have to do another round of
     propagation for everything that depends on DEST.  */
  old_last = cached_last_copy_of[dest_ver];
  new_last = get_last_copy_of (dest);
  cached_last_copy_of[dest_ver] = new_last;

  return (old_last != new_last);
}


/* Dump the copy-of value for variable VAR to FILE.  */

static void
dump_copy_of (FILE *file, tree var)
{
  tree val;
  sbitmap visited;

  print_generic_expr (file, var, dump_flags);

  if (TREE_CODE (var) != SSA_NAME)
    return;
    
  visited = sbitmap_alloc (num_ssa_names);
  sbitmap_zero (visited);
  SET_BIT (visited, SSA_NAME_VERSION (var));
  
  fprintf (file, " copy-of chain: ");

  val = var;
  print_generic_expr (file, val, 0);
  fprintf (file, " ");
  while (copy_of[SSA_NAME_VERSION (val)].value)
    {
      fprintf (file, "-> ");
      val = copy_of[SSA_NAME_VERSION (val)].value;
      print_generic_expr (file, val, 0);
      fprintf (file, " ");
      if (TEST_BIT (visited, SSA_NAME_VERSION (val)))
        break;
      SET_BIT (visited, SSA_NAME_VERSION (val));
    }

  val = get_copy_of_val (var)->value;
  if (val == NULL_TREE)
    fprintf (file, "[UNDEFINED]");
  else if (val != var)
    fprintf (file, "[COPY]");
  else
    fprintf (file, "[NOT A COPY]");
  
  sbitmap_free (visited);
}


/* Evaluate the RHS of STMT.  If it produces a valid copy, set the LHS
   value and store the LHS into *RESULT_P.  If STMT generates more
   than one name (i.e., STMT is an aliased store), it is enough to
   store the first name in the VDEF list into *RESULT_P.  After
   all, the names generated will be VUSEd in the same statements.  */

static enum ssa_prop_result
copy_prop_visit_assignment (gimple stmt, tree *result_p)
{
  tree lhs, rhs;
  prop_value_t *rhs_val;

  lhs = gimple_assign_lhs (stmt);
  rhs = gimple_assign_rhs1 (stmt);
  

  gcc_assert (gimple_assign_rhs_code (stmt) == SSA_NAME);

  rhs_val = get_copy_of_val (rhs);

  if (TREE_CODE (lhs) == SSA_NAME)
    {
      /* Straight copy between two SSA names.  First, make sure that
	 we can propagate the RHS into uses of LHS.  */
      if (!may_propagate_copy (lhs, rhs))
	return SSA_PROP_VARYING;

      /* Notice that in the case of assignments, we make the LHS be a
	 copy of RHS's value, not of RHS itself.  This avoids keeping
	 unnecessary copy-of chains (assignments cannot be in a cycle
	 like PHI nodes), speeding up the propagation process.
	 This is different from what we do in copy_prop_visit_phi_node. 
	 In those cases, we are interested in the copy-of chains.  */
      *result_p = lhs;
      if (set_copy_of_val (*result_p, rhs_val->value))
	return SSA_PROP_INTERESTING;
      else
	return SSA_PROP_NOT_INTERESTING;
    }

  return SSA_PROP_VARYING;
}


/* Visit the GIMPLE_COND STMT.  Return SSA_PROP_INTERESTING
   if it can determine which edge will be taken.  Otherwise, return
   SSA_PROP_VARYING.  */

static enum ssa_prop_result
copy_prop_visit_cond_stmt (gimple stmt, edge *taken_edge_p)
{
  enum ssa_prop_result retval = SSA_PROP_VARYING;

  tree op0 = gimple_cond_lhs (stmt);
  tree op1 = gimple_cond_rhs (stmt);

  /* The only conditionals that we may be able to compute statically
     are predicates involving two SSA_NAMEs.  */
  if (TREE_CODE (op0) == SSA_NAME && TREE_CODE (op1) == SSA_NAME)
    {
      op0 = get_last_copy_of (op0);
      op1 = get_last_copy_of (op1);

      /* See if we can determine the predicate's value.  */
      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "Trying to determine truth value of ");
	  fprintf (dump_file, "predicate ");
	  print_gimple_stmt (dump_file, stmt, 0, 0);
	}

      /* We can fold COND and get a useful result only when we have
	 the same SSA_NAME on both sides of a comparison operator.  */
      if (op0 == op1)
	{
	  tree folded_cond = fold_binary (gimple_cond_code (stmt),
                                          boolean_type_node, op0, op1);
	  if (folded_cond)
	    {
	      basic_block bb = gimple_bb (stmt);
	      *taken_edge_p = find_taken_edge (bb, folded_cond);
	      if (*taken_edge_p)
		retval = SSA_PROP_INTERESTING;
	    }
	}
    }

  if (dump_file && (dump_flags & TDF_DETAILS) && *taken_edge_p)
    fprintf (dump_file, "\nConditional will always take edge %d->%d\n",
	     (*taken_edge_p)->src->index, (*taken_edge_p)->dest->index);

  return retval;
}


/* Evaluate statement STMT.  If the statement produces a new output
   value, return SSA_PROP_INTERESTING and store the SSA_NAME holding
   the new value in *RESULT_P.

   If STMT is a conditional branch and we can determine its truth
   value, set *TAKEN_EDGE_P accordingly.

   If the new value produced by STMT is varying, return
   SSA_PROP_VARYING.  */

static enum ssa_prop_result
copy_prop_visit_stmt (gimple stmt, edge *taken_edge_p, tree *result_p)
{
  enum ssa_prop_result retval;

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "\nVisiting statement:\n");
      print_gimple_stmt (dump_file, stmt, 0, dump_flags);
      fprintf (dump_file, "\n");
    }

  if (gimple_assign_single_p (stmt)
      && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME
      && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
    {
      /* If the statement is a copy assignment, evaluate its RHS to
	 see if the lattice value of its output has changed.  */
      retval = copy_prop_visit_assignment (stmt, result_p);
    }
  else if (gimple_code (stmt) == GIMPLE_COND)
    {
      /* See if we can determine which edge goes out of a conditional
	 jump.  */
      retval = copy_prop_visit_cond_stmt (stmt, taken_edge_p);
    }
  else
    retval = SSA_PROP_VARYING;

  if (retval == SSA_PROP_VARYING)
    {
      tree def;
      ssa_op_iter i;

      /* Any other kind of statement is not interesting for constant
	 propagation and, therefore, not worth simulating.  */
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "No interesting values produced.\n");

      /* The assignment is not a copy operation.  Don't visit this
	 statement again and mark all the definitions in the statement
	 to be copies of nothing.  */
      FOR_EACH_SSA_TREE_OPERAND (def, stmt, i, SSA_OP_ALL_DEFS)
	set_copy_of_val (def, def);
    }

  return retval;
}


/* Visit PHI node PHI.  If all the arguments produce the same value,
   set it to be the value of the LHS of PHI.  */

static enum ssa_prop_result
copy_prop_visit_phi_node (gimple phi)
{
  enum ssa_prop_result retval;
  unsigned i;
  prop_value_t phi_val = { 0, NULL_TREE };

  tree lhs = gimple_phi_result (phi);

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "\nVisiting PHI node: ");
      print_gimple_stmt (dump_file, phi, 0, dump_flags);
      fprintf (dump_file, "\n\n");
    }

  for (i = 0; i < gimple_phi_num_args (phi); i++)
    {
      prop_value_t *arg_val;
      tree arg = gimple_phi_arg_def (phi, i);
      edge e = gimple_phi_arg_edge (phi, i);

      /* We don't care about values flowing through non-executable
	 edges.  */
      if (!(e->flags & EDGE_EXECUTABLE))
	continue;

      /* Constants in the argument list never generate a useful copy.
	 Similarly, names that flow through abnormal edges cannot be
	 used to derive copies.  */
      if (TREE_CODE (arg) != SSA_NAME || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (arg))
	{
	  phi_val.value = lhs;
	  break;
	}

      /* Avoid copy propagation from an inner into an outer loop.
	 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 (arg) > loop_depth_of_name (lhs))
	{
	  phi_val.value = lhs;
	  break;
	}

      /* If the LHS appears in the argument list, ignore it.  It is
	 irrelevant as a copy.  */
      if (arg == lhs || get_last_copy_of (arg) == lhs)
	continue;

      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "\tArgument #%d: ", i);
	  dump_copy_of (dump_file, arg);
	  fprintf (dump_file, "\n");
	}

      arg_val = get_copy_of_val (arg);

      /* If the LHS didn't have a value yet, make it a copy of the
	 first argument we find.  Notice that while we make the LHS be
	 a copy of the argument itself, we take the memory reference
	 from the argument's value so that we can compare it to the
	 memory reference of all the other arguments.  */
      if (phi_val.value == NULL_TREE)
	{
	  phi_val.value = arg;
	  continue;
	}

      /* If PHI_VAL and ARG don't have a common copy-of chain, then
	 this PHI node cannot be a copy operation.  Also, if we are
	 copy propagating stores and these two arguments came from
	 different memory references, they cannot be considered
	 copies.  */
      if (get_last_copy_of (phi_val.value) != get_last_copy_of (arg))
	{
	  phi_val.value = lhs;
	  break;
	}
    }

  if (phi_val.value &&  may_propagate_copy (lhs, phi_val.value)
      && set_copy_of_val (lhs, phi_val.value))
    retval = (phi_val.value != lhs) ? SSA_PROP_INTERESTING : SSA_PROP_VARYING;
  else
    retval = SSA_PROP_NOT_INTERESTING;

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "\nPHI node ");
      dump_copy_of (dump_file, lhs);
      fprintf (dump_file, "\nTelling the propagator to ");
      if (retval == SSA_PROP_INTERESTING)
	fprintf (dump_file, "add SSA edges out of this PHI and continue.");
      else if (retval == SSA_PROP_VARYING)
	fprintf (dump_file, "add SSA edges out of this PHI and never visit again.");
      else
	fprintf (dump_file, "do nothing with SSA edges and keep iterating.");
      fprintf (dump_file, "\n\n");
    }

  return retval;
}


/* Initialize structures used for copy propagation.   PHIS_ONLY is true
   if we should only consider PHI nodes as generating copy propagation
   opportunities.  */

static void
init_copy_prop (void)
{
  basic_block bb;

  copy_of = XCNEWVEC (prop_value_t, num_ssa_names);

  cached_last_copy_of = XCNEWVEC (tree, num_ssa_names);

  FOR_EACH_BB (bb)
    {
      gimple_stmt_iterator si;
      int depth = bb->loop_depth;

      for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
	{
	  gimple stmt = gsi_stmt (si);
	  ssa_op_iter iter;
          tree def;

	  /* The only statements that we care about are those that may
	     generate useful copies.  We also need to mark conditional
	     jumps so that their outgoing edges are added to the work
	     lists of the propagator.

	     Avoid copy propagation from an inner into an outer loop.
	     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 (stmt_ends_bb_p (stmt))
            prop_set_simulate_again (stmt, true);
	  else if (stmt_may_generate_copy (stmt)
                   /* Since we are iterating over the statements in
                      BB, not the phi nodes, STMT will always be an
                      assignment.  */
                   && loop_depth_of_name (gimple_assign_rhs1 (stmt)) <= depth)
            prop_set_simulate_again (stmt, true);
	  else
            prop_set_simulate_again (stmt, false);

	  /* Mark all the outputs of this statement as not being
	     the copy of anything.  */
	  FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
            if (!prop_simulate_again_p (stmt))
	      set_copy_of_val (def, def);
	    else
	      cached_last_copy_of[SSA_NAME_VERSION (def)] = def;
	}

      for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
	{
          gimple phi = gsi_stmt (si);
          tree def;

	  def = gimple_phi_result (phi);
	  if (!is_gimple_reg (def))
            prop_set_simulate_again (phi, false);
	  else
            prop_set_simulate_again (phi, true);

	  if (!prop_simulate_again_p (phi))
	    set_copy_of_val (def, def);
	  else
	    cached_last_copy_of[SSA_NAME_VERSION (def)] = def;
	}
    }
}


/* Deallocate memory used in copy propagation and do final
   substitution.  */

static void
fini_copy_prop (void)
{
  size_t i;
  prop_value_t *tmp;
  
  /* Set the final copy-of value for each variable by traversing the
     copy-of chains.  */
  tmp = XCNEWVEC (prop_value_t, num_ssa_names);
  for (i = 1; i < num_ssa_names; i++)
    {
      tree var = ssa_name (i);
      if (var && copy_of[i].value && copy_of[i].value != var)
	tmp[i].value = get_last_copy_of (var);
    }

  substitute_and_fold (tmp, false);

  free (cached_last_copy_of);
  free (copy_of);
  free (tmp);
}


/* Main entry point to the copy propagator.

   PHIS_ONLY is true if we should only consider PHI nodes as generating
   copy propagation opportunities. 

   The algorithm propagates the value COPY-OF using ssa_propagate.  For
   every variable X_i, COPY-OF(X_i) indicates which variable is X_i created
   from.  The following example shows how the algorithm proceeds at a
   high level:

	    1	a_24 = x_1
	    2	a_2 = PHI <a_24, x_1>
	    3	a_5 = PHI <a_2>
	    4	x_1 = PHI <x_298, a_5, a_2>

   The end result should be that a_2, a_5, a_24 and x_1 are a copy of
   x_298.  Propagation proceeds as follows.

   Visit #1: a_24 is copy-of x_1.  Value changed.
   Visit #2: a_2 is copy-of x_1.  Value changed.
   Visit #3: a_5 is copy-of x_1.  Value changed.
   Visit #4: x_1 is copy-of x_298.  Value changed.
   Visit #1: a_24 is copy-of x_298.  Value changed.
   Visit #2: a_2 is copy-of x_298.  Value changed.
   Visit #3: a_5 is copy-of x_298.  Value changed.
   Visit #4: x_1 is copy-of x_298.  Stable state reached.
   
   When visiting PHI nodes, we only consider arguments that flow
   through edges marked executable by the propagation engine.  So,
   when visiting statement #2 for the first time, we will only look at
   the first argument (a_24) and optimistically assume that its value
   is the copy of a_24 (x_1).

   The problem with this approach is that it may fail to discover copy
   relations in PHI cycles.  Instead of propagating copy-of
   values, we actually propagate copy-of chains.  For instance:

   		A_3 = B_1;
		C_9 = A_3;
		D_4 = C_9;
		X_i = D_4;

   In this code fragment, COPY-OF (X_i) = { D_4, C_9, A_3, B_1 }.
   Obviously, we are only really interested in the last value of the
   chain, however the propagator needs to access the copy-of chain
   when visiting PHI nodes.

   To represent the copy-of chain, we use the array COPY_CHAINS, which
   holds the first link in the copy-of chain for every variable.
   If variable X_i is a copy of X_j, which in turn is a copy of X_k,
   the array will contain:

		COPY_CHAINS[i] = X_j
		COPY_CHAINS[j] = X_k
		COPY_CHAINS[k] = X_k

   Keeping copy-of chains instead of copy-of values directly becomes
   important when visiting PHI nodes.  Suppose that we had the
   following PHI cycle, such that x_52 is already considered a copy of
   x_53:

	    1	x_54 = PHI <x_53, x_52>
	    2	x_53 = PHI <x_898, x_54>
   
   Visit #1: x_54 is copy-of x_53 (because x_52 is copy-of x_53)
   Visit #2: x_53 is copy-of x_898 (because x_54 is a copy of x_53,
				    so it is considered irrelevant
				    as a copy).
   Visit #1: x_54 is copy-of nothing (x_53 is a copy-of x_898 and
				      x_52 is a copy of x_53, so
				      they don't match)
   Visit #2: x_53 is copy-of nothing

   This problem is avoided by keeping a chain of copies, instead of
   the final copy-of value.  Propagation will now only keep the first
   element of a variable's copy-of chain.  When visiting PHI nodes,
   arguments are considered equal if their copy-of chains end in the
   same variable.  So, as long as their copy-of chains overlap, we
   know that they will be a copy of the same variable, regardless of
   which variable that may be).
   
   Propagation would then proceed as follows (the notation a -> b
   means that a is a copy-of b):

   Visit #1: x_54 = PHI <x_53, x_52>
		x_53 -> x_53
		x_52 -> x_53
		Result: x_54 -> x_53.  Value changed.  Add SSA edges.

   Visit #1: x_53 = PHI <x_898, x_54>
   		x_898 -> x_898
		x_54 -> x_53
		Result: x_53 -> x_898.  Value changed.  Add SSA edges.

   Visit #2: x_54 = PHI <x_53, x_52>
   		x_53 -> x_898
		x_52 -> x_53 -> x_898
		Result: x_54 -> x_898.  Value changed.  Add SSA edges.

   Visit #2: x_53 = PHI <x_898, x_54>
   		x_898 -> x_898
		x_54 -> x_898
		Result: x_53 -> x_898.  Value didn't change.  Stable state

   Once the propagator stabilizes, we end up with the desired result
   x_53 and x_54 are both copies of x_898.  */

static unsigned int
execute_copy_prop (void)
{
  init_copy_prop ();
  ssa_propagate (copy_prop_visit_stmt, copy_prop_visit_phi_node);
  fini_copy_prop ();
  return 0;
}

static bool
gate_copy_prop (void)
{
  return flag_tree_copy_prop != 0;
}

struct gimple_opt_pass pass_copy_prop =
{
 {
  GIMPLE_PASS,
  "copyprop",				/* name */
  gate_copy_prop,			/* gate */
  execute_copy_prop,			/* execute */
  NULL,					/* sub */
  NULL,					/* next */
  0,					/* static_pass_number */
  TV_TREE_COPY_PROP,			/* tv_id */
  PROP_ssa | PROP_cfg,			/* properties_required */
  0,					/* properties_provided */
  0,					/* properties_destroyed */
  0,					/* todo_flags_start */
  TODO_cleanup_cfg
    | TODO_dump_func
    | TODO_ggc_collect
    | TODO_verify_ssa
    | TODO_update_ssa			/* todo_flags_finish */
 }
};
