/* Back-propagation of usage information to definitions.
   Copyright (C) 2015-2017 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/>.  */

/* This pass propagates information that is common to all uses of an SSA
   name back up through the sequence of statements that generate it,
   simplifying the statements where possible.  Sometimes this can expose
   fully or partially dead code, but the main focus is simplifying
   computations.

   At the moment the pass only handles one piece of information: whether the
   sign of a value matters, and therefore whether sign-changing operations
   can be skipped.  The pass could be extended to more interesting
   information in future, such as which bits of an integer are significant.

   For example, take the function:

     double
     f (double *a, int n, double start)
     {
       double x = fabs (start);
       for (int i = 0; i < n; ++i)
	 x *= a[i];
       return __builtin_cos (x);
     }

   cos(x) == cos(-x), so the sign of the final x doesn't matter.
   That x is the result of a series of multiplications, and if
   the sign of the result of a multiplication doesn't matter,
   the signs of the inputs don't matter either.

   The pass would replace the incoming value of x (i.e. fabs(start))
   with start.  Since there are no other uses of the fabs result,
   the call would get deleted as dead.

   The algorithm is:

   (1) Do a post-order traversal of the blocks in the function, walking
       each block backwards.  For each potentially-simplifiable statement
       that defines an SSA name X, examine all uses of X to see what
       information is actually significant.  Record this as INFO_MAP[X].
       Optimistically ignore for now any back-edge references to
       unprocessed phis.

       (An alternative would be to record each use when we visit its
       statement and take the intersection as we go along.  However,
       this would lead to more SSA names being entered into INFO_MAP
       unnecessarily, only to be taken out again later.  At the moment
       very few SSA names end up with useful information.)

   (2) Iteratively reduce the optimistic result of (1) until we reach
       a maximal fixed point (which at the moment would mean revisiting
       statements at most once).  First push all SSA names that used an
       optimistic assumption about a backedge phi onto a worklist.
       While the worklist is nonempty, pick off an SSA name X and recompute
       INFO_MAP[X].  If the value changes, push all SSA names used in the
       definition of X onto the worklist.

   (3) Iterate over each SSA name X with info in INFO_MAP, in the
       opposite order to (1), i.e. a forward reverse-post-order walk.
       Try to optimize the definition of X using INFO_MAP[X] and fold
       the result.  (This ensures that we fold definitions before uses.)

   (4) Iterate over each SSA name X with info in INFO_MAP, in the same
       order as (1), and delete any statements that are now dead.
       (This ensures that if a sequence of statements is dead,
       we delete the last statement first.)

   Note that this pass does not deal with direct redundancies,
   such as cos(-x)->cos(x).  match.pd handles those cases instead.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "ssa.h"
#include "fold-const.h"
#include "tree-pass.h"
#include "cfganal.h"
#include "gimple-pretty-print.h"
#include "tree-cfg.h"
#include "tree-ssa.h"
#include "tree-ssa-propagate.h"
#include "gimple-fold.h"
#include "alloc-pool.h"
#include "tree-hash-traits.h"
#include "case-cfn-macros.h"

namespace {

/* Information about a group of uses of an SSA name.  */
struct usage_info
{
  usage_info () : flag_word (0) {}
  usage_info &operator &= (const usage_info &);
  usage_info operator & (const usage_info &) const;
  bool operator == (const usage_info &) const;
  bool operator != (const usage_info &) const;
  bool is_useful () const;

  static usage_info intersection_identity ();

  union
  {
    struct
    {
      /* True if the uses treat x and -x in the same way.  */
      unsigned int ignore_sign : 1;
    } flags;
    /* All the flag bits as a single int.  */
    unsigned int flag_word;
  };
};

/* Return an X such that X & Y == Y for all Y.  This is the most
   optimistic assumption possible.  */

usage_info
usage_info::intersection_identity ()
{
  usage_info ret;
  ret.flag_word = -1;
  return ret;
}

/* Intersect *THIS with OTHER, so that *THIS describes all uses covered
   by the original *THIS and OTHER.  */

usage_info &
usage_info::operator &= (const usage_info &other)
{
  flag_word &= other.flag_word;
  return *this;
}

/* Return the intersection of *THIS and OTHER, i.e. a structure that
   describes all uses covered by *THIS and OTHER.  */

usage_info
usage_info::operator & (const usage_info &other) const
{
  usage_info info (*this);
  info &= other;
  return info;
}

bool
usage_info::operator == (const usage_info &other) const
{
  return flag_word == other.flag_word;
}

bool
usage_info::operator != (const usage_info &other) const
{
  return !operator == (other);
}

/* Return true if *THIS is not simply the default, safe assumption.  */

bool
usage_info::is_useful () const
{
  return flag_word != 0;
}

/* Start a dump line about SSA name VAR.  */

static void
dump_usage_prefix (FILE *file, tree var)
{
  fprintf (file, "  ");
  print_generic_expr (file, var, 0);
  fprintf (file, ": ");
}

/* Print INFO to FILE.  */

static void
dump_usage_info (FILE *file, tree var, usage_info *info)
{
  if (info->flags.ignore_sign)
    {
      dump_usage_prefix (file, var);
      fprintf (file, "sign bit not important\n");
    }
}

/* Represents one execution of the pass.  */
class backprop
{
public:
  backprop (function *);
  ~backprop ();

  void execute ();

private:
  const usage_info *lookup_operand (tree);

  void push_to_worklist (tree);
  tree pop_from_worklist ();

  void process_builtin_call_use (gcall *, tree, usage_info *);
  void process_assign_use (gassign *, tree, usage_info *);
  void process_phi_use (gphi *, usage_info *);
  void process_use (gimple *, tree, usage_info *);
  bool intersect_uses (tree, usage_info *);
  void reprocess_inputs (gimple *);
  void process_var (tree);
  void process_block (basic_block);

  void prepare_change (tree);
  void complete_change (gimple *);
  void optimize_builtin_call (gcall *, tree, const usage_info *);
  void replace_assign_rhs (gassign *, tree, tree, tree, tree);
  void optimize_assign (gassign *, tree, const usage_info *);
  void optimize_phi (gphi *, tree, const usage_info *);

  typedef hash_map <tree_ssa_name_hash, usage_info *> info_map_type;
  typedef std::pair <tree, usage_info *> var_info_pair;

  /* The function we're optimizing.  */
  function *m_fn;

  /* Pool for allocating usage_info structures.  */
  object_allocator <usage_info> m_info_pool;

  /* Maps an SSA name to a description of all uses of that SSA name.
     All the usage_infos satisfy is_useful.

     We use a hash_map because the map is expected to be sparse
     (i.e. most SSA names won't have useful information attached to them).
     We could move to a directly-indexed array if that situation changes.  */
  info_map_type m_info_map;

  /* Post-ordered list of all potentially-interesting SSA names,
     along with information that describes all uses.  */
  auto_vec <var_info_pair, 128> m_vars;

  /* A bitmap of blocks that we have finished processing in the initial
     post-order walk.  */
  auto_sbitmap m_visited_blocks;

  /* A bitmap of phis that we have finished processing in the initial
     post-order walk, excluding those from blocks mentioned in
     M_VISITED_BLOCKS.  */
  auto_bitmap m_visited_phis;

  /* A worklist of SSA names whose definitions need to be reconsidered.  */
  auto_vec <tree, 64> m_worklist;

  /* The SSA names in M_WORKLIST, identified by their SSA_NAME_VERSION.
     We use a bitmap rather than an sbitmap because most SSA names are
     never added to the worklist.  */
  bitmap m_worklist_names;
};

backprop::backprop (function *fn)
  : m_fn (fn),
    m_info_pool ("usage_info"),
    m_visited_blocks (last_basic_block_for_fn (m_fn)),
    m_worklist_names (BITMAP_ALLOC (NULL))
{
  bitmap_clear (m_visited_blocks);
}

backprop::~backprop ()
{
  BITMAP_FREE (m_worklist_names);
  m_info_pool.release ();
}

/* Return usage information for general operand OP, or null if none.  */

const usage_info *
backprop::lookup_operand (tree op)
{
  if (op && TREE_CODE (op) == SSA_NAME)
    {
      usage_info **slot = m_info_map.get (op);
      if (slot)
	return *slot;
    }
  return NULL;
}

/* Add SSA name VAR to the worklist, if it isn't on the worklist already.  */

void
backprop::push_to_worklist (tree var)
{
  if (!bitmap_set_bit (m_worklist_names, SSA_NAME_VERSION (var)))
    return;
  m_worklist.safe_push (var);
  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "[WORKLIST] Pushing ");
      print_generic_expr (dump_file, var, 0);
      fprintf (dump_file, "\n");
    }
}

/* Remove and return the next SSA name from the worklist.  The worklist
   is known to be nonempty.  */

tree
backprop::pop_from_worklist ()
{
  tree var = m_worklist.pop ();
  bitmap_clear_bit (m_worklist_names, SSA_NAME_VERSION (var));
  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "[WORKLIST] Popping ");
      print_generic_expr (dump_file, var, 0);
      fprintf (dump_file, "\n");
    }
  return var;
}

/* Make INFO describe all uses of RHS in CALL, which is a call to a
   built-in function.  */

void
backprop::process_builtin_call_use (gcall *call, tree rhs, usage_info *info)
{
  combined_fn fn = gimple_call_combined_fn (call);
  tree lhs = gimple_call_lhs (call);
  switch (fn)
    {
    case CFN_LAST:
      break;

    CASE_CFN_COS:
    CASE_CFN_COSH:
    CASE_CFN_CCOS:
    CASE_CFN_CCOSH:
    CASE_CFN_HYPOT:
      /* The signs of all inputs are ignored.  */
      info->flags.ignore_sign = true;
      break;

    CASE_CFN_COPYSIGN:
      /* The sign of the first input is ignored.  */
      if (rhs != gimple_call_arg (call, 1))
	info->flags.ignore_sign = true;
      break;

    CASE_CFN_POW:
      {
	/* The sign of the first input is ignored as long as the second
	   input is an even real.  */
	tree power = gimple_call_arg (call, 1);
	HOST_WIDE_INT n;
	if (TREE_CODE (power) == REAL_CST
	    && real_isinteger (&TREE_REAL_CST (power), &n)
	    && (n & 1) == 0)
	  info->flags.ignore_sign = true;
	break;
      }

    CASE_CFN_FMA:
      /* In X * X + Y, where Y is distinct from X, the sign of X doesn't
	 matter.  */
      if (gimple_call_arg (call, 0) == rhs
	  && gimple_call_arg (call, 1) == rhs
	  && gimple_call_arg (call, 2) != rhs)
	info->flags.ignore_sign = true;
      break;

    default:
      if (negate_mathfn_p (fn))
	{
	  /* The sign of the (single) input doesn't matter provided
	     that the sign of the output doesn't matter.  */
	  const usage_info *lhs_info = lookup_operand (lhs);
	  if (lhs_info)
	    info->flags.ignore_sign = lhs_info->flags.ignore_sign;
	}
      break;
    }
}

/* Make INFO describe all uses of RHS in ASSIGN.  */

void
backprop::process_assign_use (gassign *assign, tree rhs, usage_info *info)
{
  tree lhs = gimple_assign_lhs (assign);
  switch (gimple_assign_rhs_code (assign))
    {
    case ABS_EXPR:
      /* The sign of the input doesn't matter.  */
      info->flags.ignore_sign = true;
      break;

    case COND_EXPR:
      /* For A = B ? C : D, propagate information about all uses of A
	 to C and D.  */
      if (rhs != gimple_assign_rhs1 (assign))
	{
	  const usage_info *lhs_info = lookup_operand (lhs);
	  if (lhs_info)
	    *info = *lhs_info;
	}
      break;

    case FMA_EXPR:
      /* In X * X + Y, where Y is distinct from X, the sign of X doesn't
	 matter.  */
      if (gimple_assign_rhs1 (assign) == rhs
	  && gimple_assign_rhs2 (assign) == rhs
	  && gimple_assign_rhs3 (assign) != rhs)
	info->flags.ignore_sign = true;
      break;

    case MULT_EXPR:
      /* In X * X, the sign of X doesn't matter.  */
      if (gimple_assign_rhs1 (assign) == rhs
	  && gimple_assign_rhs2 (assign) == rhs)
	info->flags.ignore_sign = true;
      /* Fall through.  */

    case NEGATE_EXPR:
    case RDIV_EXPR:
      /* If the sign of the result doesn't matter, the sign of the inputs
	 doesn't matter either.  */
      if (FLOAT_TYPE_P (TREE_TYPE (rhs)))
	{
	  const usage_info *lhs_info = lookup_operand (lhs);
	  if (lhs_info)
	    info->flags.ignore_sign = lhs_info->flags.ignore_sign;
	}
      break;

    default:
      break;
    }
}

/* Make INFO describe the uses of PHI's result.  */

void
backprop::process_phi_use (gphi *phi, usage_info *info)
{
  tree result = gimple_phi_result (phi);
  if (const usage_info *result_info = lookup_operand (result))
    *info = *result_info;
}

/* Make INFO describe all uses of RHS in STMT.  */

void
backprop::process_use (gimple *stmt, tree rhs, usage_info *info)
{
  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "[USE] ");
      print_generic_expr (dump_file, rhs, 0);
      fprintf (dump_file, " in ");
      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
    }

  if (gcall *call = dyn_cast <gcall *> (stmt))
    process_builtin_call_use (call, rhs, info);
  else if (gassign *assign = dyn_cast <gassign *> (stmt))
    process_assign_use (assign, rhs, info);
  else if (gphi *phi = dyn_cast <gphi *> (stmt))
    process_phi_use (phi, info);

  if (dump_file && (dump_flags & TDF_DETAILS))
    dump_usage_info (dump_file, rhs, info);
}

/* Make INFO describe all uses of VAR, returning true if the result
   is useful.  If the uses include phis that haven't been processed yet,
   make the most optimistic assumption possible, so that we aim for
   a maximum rather than a minimum fixed point.  */

bool
backprop::intersect_uses (tree var, usage_info *info)
{
  imm_use_iterator iter;
  gimple *stmt;
  *info = usage_info::intersection_identity ();
  FOR_EACH_IMM_USE_STMT (stmt, iter, var)
    {
      if (is_gimple_debug (stmt))
	continue;
      gphi *phi = dyn_cast <gphi *> (stmt);
      if (phi
	  && !bitmap_bit_p (m_visited_blocks, gimple_bb (phi)->index)
	  && !bitmap_bit_p (m_visited_phis,
			    SSA_NAME_VERSION (gimple_phi_result (phi))))
	{
	  /* Skip unprocessed phis.  */
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "[BACKEDGE] ");
	      print_generic_expr (dump_file, var, 0);
	      fprintf (dump_file, " in ");
	      print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
	    }
	}
      else
	{
	  usage_info subinfo;
	  process_use (stmt, var, &subinfo);
	  *info &= subinfo;
	  if (!info->is_useful ())
	    {
	      BREAK_FROM_IMM_USE_STMT (iter);
	      return false;
	    }
	}
    }
  return true;
}

/* Queue for reconsideration any input of STMT that has information
   associated with it.  This is used if that information might be
   too optimistic.  */

void
backprop::reprocess_inputs (gimple *stmt)
{
  use_operand_p use_p;
  ssa_op_iter oi;
  FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, oi, SSA_OP_USE)
    {
      tree var = get_use_from_ptr (use_p);
      if (lookup_operand (var))
	push_to_worklist (var);
    }
}

/* Say that we're recording INFO for SSA name VAR, or that we're deleting
   existing information if INFO is null.  INTRO describes the change.  */

static void
dump_var_info (tree var, usage_info *info, const char *intro)
{
  fprintf (dump_file, "[DEF] %s for ", intro);
  print_gimple_stmt (dump_file, SSA_NAME_DEF_STMT (var), 0, TDF_SLIM);
  if (info)
    dump_usage_info (dump_file, var, info);
}

/* Process all uses of VAR and record or update the result in
   M_INFO_MAP and M_VARS.  */

void
backprop::process_var (tree var)
{
  if (has_zero_uses (var))
    return;

  usage_info info;
  intersect_uses (var, &info);

  gimple *stmt = SSA_NAME_DEF_STMT (var);
  if (info.is_useful ())
    {
      bool existed;
      usage_info *&map_info = m_info_map.get_or_insert (var, &existed);
      if (!existed)
	{
	  /* Recording information about VAR for the first time.  */
	  map_info = m_info_pool.allocate ();
	  *map_info = info;
	  m_vars.safe_push (var_info_pair (var, map_info));
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    dump_var_info (var, map_info, "Recording new information");

	  /* If STMT is a phi, reprocess any backedge uses.  This is a
	     no-op for other uses, which won't have any information
	     associated with them.  */
	  if (is_a <gphi *> (stmt))
	    reprocess_inputs (stmt);
	}
      else if (info != *map_info)
	{
	  /* Recording information that is less optimistic than before.  */
	  gcc_checking_assert ((info & *map_info) == info);
	  *map_info = info;
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    dump_var_info (var, map_info, "Updating information");
	  reprocess_inputs (stmt);
	}
    }
  else
    {
      if (usage_info **slot = m_info_map.get (var))
	{
	  /* Removing previously-recorded information.  */
	  **slot = info;
	  m_info_map.remove (var);
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    dump_var_info (var, NULL, "Deleting information");
	  reprocess_inputs (stmt);
	}
      else
	{
	  /* If STMT is a phi, remove any information recorded for
	     its arguments.  */
	  if (is_a <gphi *> (stmt))
	    reprocess_inputs (stmt);
	}
    }
}

/* Process all statements and phis in BB, during the first post-order walk.  */

void
backprop::process_block (basic_block bb)
{
  for (gimple_stmt_iterator gsi = gsi_last_bb (bb); !gsi_end_p (gsi);
       gsi_prev (&gsi))
    {
      tree lhs = gimple_get_lhs (gsi_stmt (gsi));
      if (lhs && TREE_CODE (lhs) == SSA_NAME)
	process_var (lhs);
    }
  for (gphi_iterator gpi = gsi_start_phis (bb); !gsi_end_p (gpi);
       gsi_next (&gpi))
    {
      tree result = gimple_phi_result (gpi.phi ());
      process_var (result);
      bitmap_set_bit (m_visited_phis, SSA_NAME_VERSION (result));
    }
  bitmap_clear (m_visited_phis);
}

/* Delete the definition of VAR, which has no uses.  */

static void
remove_unused_var (tree var)
{
  gimple *stmt = SSA_NAME_DEF_STMT (var);
  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Deleting ");
      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
    }
  gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
  gsi_remove (&gsi, true);
  release_defs (stmt);
}

/* Note that we're replacing OLD_RHS with NEW_RHS in STMT.  */

static void
note_replacement (gimple *stmt, tree old_rhs, tree new_rhs)
{
  fprintf (dump_file, "Replacing use of ");
  print_generic_expr (dump_file, old_rhs, 0);
  fprintf (dump_file, " with ");
  print_generic_expr (dump_file, new_rhs, 0);
  fprintf (dump_file, " in ");
  print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
}

/* If RHS is an SSA name whose definition just changes the sign of a value,
   return that other value, otherwise return null.  */

static tree
strip_sign_op_1 (tree rhs)
{
  if (TREE_CODE (rhs) != SSA_NAME)
    return NULL_TREE;

  gimple *def_stmt = SSA_NAME_DEF_STMT (rhs);
  if (gassign *assign = dyn_cast <gassign *> (def_stmt))
    switch (gimple_assign_rhs_code (assign))
      {
      case ABS_EXPR:
      case NEGATE_EXPR:
	return gimple_assign_rhs1 (assign);

      default:
	break;
      }
  else if (gcall *call = dyn_cast <gcall *> (def_stmt))
    switch (gimple_call_combined_fn (call))
      {
      CASE_CFN_COPYSIGN:
	return gimple_call_arg (call, 0);

      default:
	break;
      }

  return NULL_TREE;
}

/* If RHS is an SSA name whose definition just changes the sign of a value,
   strip all such operations and return the ultimate input to them.
   Return null otherwise.

   Although this could in principle lead to quadratic searching,
   in practice a long sequence of sign manipulations should already
   have been folded down.  E.g. --x -> x, abs(-x) -> abs(x).  We search
   for more than one operation in order to catch cases like -abs(x).  */

static tree
strip_sign_op (tree rhs)
{
  tree new_rhs = strip_sign_op_1 (rhs);
  if (!new_rhs)
    return NULL_TREE;
  while (tree next = strip_sign_op_1 (new_rhs))
    new_rhs = next;
  return new_rhs;
}

/* Start a change in the value of VAR that is suitable for all non-debug
   uses of VAR.  We need to make sure that debug statements continue to
   use the original definition of VAR where possible, or are nullified
   otherwise.  */

void
backprop::prepare_change (tree var)
{
  if (MAY_HAVE_DEBUG_STMTS)
    insert_debug_temp_for_var_def (NULL, var);
  reset_flow_sensitive_info (var);
}

/* STMT has been changed.  Give the fold machinery a chance to simplify
   and canonicalize it (e.g. by ensuring that commutative operands have
   the right order), then record the updates.  */

void
backprop::complete_change (gimple *stmt)
{
  gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
  if (fold_stmt (&gsi))
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "  which folds to: ");
	  print_gimple_stmt (dump_file, gsi_stmt (gsi), 0, TDF_SLIM);
	}
    }
  update_stmt (gsi_stmt (gsi));
}

/* Optimize CALL, a call to a built-in function with lhs LHS, on the
   basis that INFO describes all uses of LHS.  */

void
backprop::optimize_builtin_call (gcall *call, tree lhs, const usage_info *info)
{
  /* If we have an f such that -f(x) = f(-x), and if the sign of the result
     doesn't matter, strip any sign operations from the input.  */
  if (info->flags.ignore_sign
      && negate_mathfn_p (gimple_call_combined_fn (call)))
    {
      tree new_arg = strip_sign_op (gimple_call_arg (call, 0));
      if (new_arg)
	{
	  prepare_change (lhs);
	  gimple_call_set_arg (call, 0, new_arg);
	  complete_change (call);
	}
    }
}

/* Optimize ASSIGN, an assignment to LHS, by replacing rhs operand N
   with RHS<N>, if RHS<N> is nonnull.  This may change the value of LHS.  */

void
backprop::replace_assign_rhs (gassign *assign, tree lhs, tree rhs1,
			      tree rhs2, tree rhs3)
{
  if (!rhs1 && !rhs2 && !rhs3)
    return;

  prepare_change (lhs);
  if (rhs1)
    gimple_assign_set_rhs1 (assign, rhs1);
  if (rhs2)
    gimple_assign_set_rhs2 (assign, rhs2);
  if (rhs3)
    gimple_assign_set_rhs3 (assign, rhs3);
  complete_change (assign);
}

/* Optimize ASSIGN, an assignment to LHS, on the basis that INFO
   describes all uses of LHS.  */

void
backprop::optimize_assign (gassign *assign, tree lhs, const usage_info *info)
{
  switch (gimple_assign_rhs_code (assign))
    {
    case MULT_EXPR:
    case RDIV_EXPR:
      /* If the sign of the result doesn't matter, strip sign operations
	 from both inputs.  */
      if (info->flags.ignore_sign)
	replace_assign_rhs (assign, lhs,
			    strip_sign_op (gimple_assign_rhs1 (assign)),
			    strip_sign_op (gimple_assign_rhs2 (assign)),
			    NULL_TREE);
      break;

    case COND_EXPR:
      /* If the sign of A ? B : C doesn't matter, strip sign operations
	 from both B and C.  */
      if (info->flags.ignore_sign)
	replace_assign_rhs (assign, lhs,
			    NULL_TREE,
			    strip_sign_op (gimple_assign_rhs2 (assign)),
			    strip_sign_op (gimple_assign_rhs3 (assign)));
      break;

    default:
      break;
    }
}

/* Optimize PHI, which defines VAR, on the basis that INFO describes all
   uses of the result.  */

void
backprop::optimize_phi (gphi *phi, tree var, const usage_info *info)
{
  /* If the sign of the result doesn't matter, try to strip sign operations
     from arguments.  */
  if (info->flags.ignore_sign)
    {
      basic_block bb = gimple_bb (phi);
      use_operand_p use;
      ssa_op_iter oi;
      bool replaced = false;
      FOR_EACH_PHI_ARG (use, phi, oi, SSA_OP_USE)
	{
	  /* Propagating along abnormal edges is delicate, punt for now.  */
	  const int index = PHI_ARG_INDEX_FROM_USE (use);
	  if (EDGE_PRED (bb, index)->flags & EDGE_ABNORMAL)
	    continue;

	  tree new_arg = strip_sign_op (USE_FROM_PTR (use));
	  if (new_arg)
	    {
	      if (!replaced)
		prepare_change (var);
	      if (dump_file && (dump_flags & TDF_DETAILS))
		note_replacement (phi, USE_FROM_PTR (use), new_arg);
	      replace_exp (use, new_arg);
	      replaced = true;
	    }
	}
    }
}

void
backprop::execute ()
{
  /* Phase 1: Traverse the function, making optimistic assumptions
     about any phi whose definition we haven't seen.  */
  int *postorder = XNEWVEC (int, n_basic_blocks_for_fn (m_fn));
  unsigned int postorder_num = post_order_compute (postorder, false, false);
  for (unsigned int i = 0; i < postorder_num; ++i)
    {
      process_block (BASIC_BLOCK_FOR_FN (m_fn, postorder[i]));
      bitmap_set_bit (m_visited_blocks, postorder[i]);
    }
  XDELETEVEC (postorder);

  /* Phase 2: Use the initial (perhaps overly optimistic) information
     to create a maximal fixed point solution.  */
  while (!m_worklist.is_empty ())
    process_var (pop_from_worklist ());

  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "\n");

  /* Phase 3: Do a reverse post-order walk, using information about
     the uses of SSA names to optimize their definitions.  */
  for (unsigned int i = m_vars.length (); i-- > 0;)
    {
      usage_info *info = m_vars[i].second;
      if (info->is_useful ())
	{
	  tree var = m_vars[i].first;
	  gimple *stmt = SSA_NAME_DEF_STMT (var);
	  if (gcall *call = dyn_cast <gcall *> (stmt))
	    optimize_builtin_call (call, var, info);
	  else if (gassign *assign = dyn_cast <gassign *> (stmt))
	    optimize_assign (assign, var, info);
	  else if (gphi *phi = dyn_cast <gphi *> (stmt))
	    optimize_phi (phi, var, info);
	}
    }

  /* Phase 4: Do a post-order walk, deleting statements that are no
     longer needed.  */
  for (unsigned int i = 0; i < m_vars.length (); ++i)
    {
      tree var = m_vars[i].first;
      if (has_zero_uses (var))
	remove_unused_var (var);
    }

  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "\n");
}

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

class pass_backprop : public gimple_opt_pass
{
public:
  pass_backprop (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_backprop, ctxt)
  {}

  /* opt_pass methods: */
  opt_pass * clone () { return new pass_backprop (m_ctxt); }
  virtual bool gate (function *) { return flag_ssa_backprop; }
  virtual unsigned int execute (function *);

}; // class pass_backprop

unsigned int
pass_backprop::execute (function *fn)
{
  backprop (fn).execute ();
  return 0;
}

} // anon namespace

gimple_opt_pass *
make_pass_backprop (gcc::context *ctxt)
{
  return new pass_backprop (ctxt);
}
