/* Dead store elimination
   Copyright (C) 2004-2019 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 "backend.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "tree-pass.h"
#include "ssa.h"
#include "gimple-pretty-print.h"
#include "fold-const.h"
#include "gimple-iterator.h"
#include "tree-cfg.h"
#include "tree-dfa.h"
#include "domwalk.h"
#include "tree-cfgcleanup.h"
#include "params.h"
#include "alias.h"
#include "tree-ssa-loop.h"
#include "gimplify.h"

/* This file implements dead store elimination.

   A dead store is a store into a memory location which will later be
   overwritten by another store without any intervening loads.  In this
   case the earlier store can be deleted.

   In our SSA + virtual operand world we use immediate uses of virtual
   operands to detect dead stores.  If a store's virtual definition
   is used precisely once by a later store to the same location which
   post dominates the first store, then the first store is dead.

   The single use of the store's virtual definition ensures that
   there are no intervening aliased loads and the requirement that
   the second load post dominate the first ensures that if the earlier
   store executes, then the later stores will execute before the function
   exits.

   It may help to think of this as first moving the earlier store to
   the point immediately before the later store.  Again, the single
   use of the virtual definition and the post-dominance relationship
   ensure that such movement would be safe.  Clearly if there are
   back to back stores, then the second is redundant.

   Reviewing section 10.7.2 in Morgan's "Building an Optimizing Compiler"
   may also help in understanding this code since it discusses the
   relationship between dead store and redundant load elimination.  In
   fact, they are the same transformation applied to different views of
   the CFG.  */


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

/* Return value from dse_classify_store */
enum dse_store_status
{
  DSE_STORE_LIVE,
  DSE_STORE_MAYBE_PARTIAL_DEAD,
  DSE_STORE_DEAD
};

/* STMT is a statement that may write into memory.  Analyze it and
   initialize WRITE to describe how STMT affects memory.

   Return TRUE if the the statement was analyzed, FALSE otherwise.

   It is always safe to return FALSE.  But typically better optimziation
   can be achieved by analyzing more statements.  */

static bool
initialize_ao_ref_for_dse (gimple *stmt, ao_ref *write)
{
  /* It's advantageous to handle certain mem* functions.  */
  if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
    {
      switch (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt)))
	{
	  case BUILT_IN_MEMCPY:
	  case BUILT_IN_MEMMOVE:
	  case BUILT_IN_MEMSET:
	    {
	      tree size = NULL_TREE;
	      if (gimple_call_num_args (stmt) == 3)
		size = gimple_call_arg (stmt, 2);
	      tree ptr = gimple_call_arg (stmt, 0);
	      ao_ref_init_from_ptr_and_size (write, ptr, size);
	      return true;
	    }
	  default:
	    break;
	}
    }
  else if (is_gimple_assign (stmt))
    {
      ao_ref_init (write, gimple_assign_lhs (stmt));
      return true;
    }
  return false;
}

/* Given REF from the the alias oracle, return TRUE if it is a valid
   memory reference for dead store elimination, false otherwise.

   In particular, the reference must have a known base, known maximum
   size, start at a byte offset and have a size that is one or more
   bytes.  */

static bool
valid_ao_ref_for_dse (ao_ref *ref)
{
  return (ao_ref_base (ref)
	  && known_size_p (ref->max_size)
	  && maybe_ne (ref->size, 0)
	  && known_eq (ref->max_size, ref->size)
	  && known_ge (ref->offset, 0)
	  && multiple_p (ref->offset, BITS_PER_UNIT)
	  && multiple_p (ref->size, BITS_PER_UNIT));
}

/* Try to normalize COPY (an ao_ref) relative to REF.  Essentially when we are
   done COPY will only refer bytes found within REF.  Return true if COPY
   is known to intersect at least one byte of REF.  */

static bool
normalize_ref (ao_ref *copy, ao_ref *ref)
{
  if (!ordered_p (copy->offset, ref->offset))
    return false;

  /* If COPY starts before REF, then reset the beginning of
     COPY to match REF and decrease the size of COPY by the
     number of bytes removed from COPY.  */
  if (maybe_lt (copy->offset, ref->offset))
    {
      poly_int64 diff = ref->offset - copy->offset;
      if (maybe_le (copy->size, diff))
	return false;
      copy->size -= diff;
      copy->offset = ref->offset;
    }

  poly_int64 diff = copy->offset - ref->offset;
  if (maybe_le (ref->size, diff))
    return false;

  /* If COPY extends beyond REF, chop off its size appropriately.  */
  poly_int64 limit = ref->size - diff;
  if (!ordered_p (limit, copy->size))
    return false;

  if (maybe_gt (copy->size, limit))
    copy->size = limit;
  return true;
}

/* Clear any bytes written by STMT from the bitmap LIVE_BYTES.  The base
   address written by STMT must match the one found in REF, which must
   have its base address previously initialized.

   This routine must be conservative.  If we don't know the offset or
   actual size written, assume nothing was written.  */

static void
clear_bytes_written_by (sbitmap live_bytes, gimple *stmt, ao_ref *ref)
{
  ao_ref write;
  if (!initialize_ao_ref_for_dse (stmt, &write))
    return;

  /* Verify we have the same base memory address, the write
     has a known size and overlaps with REF.  */
  HOST_WIDE_INT start, size;
  if (valid_ao_ref_for_dse (&write)
      && operand_equal_p (write.base, ref->base, OEP_ADDRESS_OF)
      && known_eq (write.size, write.max_size)
      && normalize_ref (&write, ref)
      && (write.offset - ref->offset).is_constant (&start)
      && write.size.is_constant (&size))
    bitmap_clear_range (live_bytes, start / BITS_PER_UNIT,
			size / BITS_PER_UNIT);
}

/* REF is a memory write.  Extract relevant information from it and
   initialize the LIVE_BYTES bitmap.  If successful, return TRUE.
   Otherwise return FALSE.  */

static bool
setup_live_bytes_from_ref (ao_ref *ref, sbitmap live_bytes)
{
  HOST_WIDE_INT const_size;
  if (valid_ao_ref_for_dse (ref)
      && ref->size.is_constant (&const_size)
      && (const_size / BITS_PER_UNIT
	  <= PARAM_VALUE (PARAM_DSE_MAX_OBJECT_SIZE)))
    {
      bitmap_clear (live_bytes);
      bitmap_set_range (live_bytes, 0, const_size / BITS_PER_UNIT);
      return true;
    }
  return false;
}

/* Compute the number of elements that we can trim from the head and
   tail of ORIG resulting in a bitmap that is a superset of LIVE.

   Store the number of elements trimmed from the head and tail in
   TRIM_HEAD and TRIM_TAIL.

   STMT is the statement being trimmed and is used for debugging dump
   output only.  */

static void
compute_trims (ao_ref *ref, sbitmap live, int *trim_head, int *trim_tail,
	       gimple *stmt)
{
  /* We use sbitmaps biased such that ref->offset is bit zero and the bitmap
     extends through ref->size.  So we know that in the original bitmap
     bits 0..ref->size were true.  We don't actually need the bitmap, just
     the REF to compute the trims.  */

  /* Now identify how much, if any of the tail we can chop off.  */
  HOST_WIDE_INT const_size;
  int last_live = bitmap_last_set_bit (live);
  if (ref->size.is_constant (&const_size))
    {
      int last_orig = (const_size / BITS_PER_UNIT) - 1;
      /* We can leave inconvenient amounts on the tail as
	 residual handling in mem* and str* functions is usually
	 reasonably efficient.  */
      *trim_tail = last_orig - last_live;

      /* But don't trim away out of bounds accesses, as this defeats
	 proper warnings.

	 We could have a type with no TYPE_SIZE_UNIT or we could have a VLA
	 where TYPE_SIZE_UNIT is not a constant.  */
      if (*trim_tail
	  && TYPE_SIZE_UNIT (TREE_TYPE (ref->base))
	  && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (ref->base))) == INTEGER_CST
	  && compare_tree_int (TYPE_SIZE_UNIT (TREE_TYPE (ref->base)),
			       last_orig) <= 0)
	*trim_tail = 0;
    }
  else
    *trim_tail = 0;

  /* Identify how much, if any of the head we can chop off.  */
  int first_orig = 0;
  int first_live = bitmap_first_set_bit (live);
  *trim_head = first_live - first_orig;

  /* If more than a word remains, then make sure to keep the
     starting point at least word aligned.  */
  if (last_live - first_live > UNITS_PER_WORD)
    *trim_head &= ~(UNITS_PER_WORD - 1);

  if ((*trim_head || *trim_tail)
      && dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "  Trimming statement (head = %d, tail = %d): ",
	       *trim_head, *trim_tail);
      print_gimple_stmt (dump_file, stmt, 0, dump_flags);
      fprintf (dump_file, "\n");
    }
}

/* STMT initializes an object from COMPLEX_CST where one or more of the
   bytes written may be dead stores.  REF is a representation of the
   memory written.  LIVE is the bitmap of stores that are actually live.

   Attempt to rewrite STMT so that only the real or imaginary part of
   the object is actually stored.  */

static void
maybe_trim_complex_store (ao_ref *ref, sbitmap live, gimple *stmt)
{
  int trim_head, trim_tail;
  compute_trims (ref, live, &trim_head, &trim_tail, stmt);

  /* The amount of data trimmed from the head or tail must be at
     least half the size of the object to ensure we're trimming
     the entire real or imaginary half.  By writing things this
     way we avoid more O(n) bitmap operations.  */
  if (known_ge (trim_tail * 2 * BITS_PER_UNIT, ref->size))
    {
      /* TREE_REALPART is live */
      tree x = TREE_REALPART (gimple_assign_rhs1 (stmt));
      tree y = gimple_assign_lhs (stmt);
      y = build1 (REALPART_EXPR, TREE_TYPE (x), y);
      gimple_assign_set_lhs (stmt, y);
      gimple_assign_set_rhs1 (stmt, x);
    }
  else if (known_ge (trim_head * 2 * BITS_PER_UNIT, ref->size))
    {
      /* TREE_IMAGPART is live */
      tree x = TREE_IMAGPART (gimple_assign_rhs1 (stmt));
      tree y = gimple_assign_lhs (stmt);
      y = build1 (IMAGPART_EXPR, TREE_TYPE (x), y);
      gimple_assign_set_lhs (stmt, y);
      gimple_assign_set_rhs1 (stmt, x);
    }

  /* Other cases indicate parts of both the real and imag subobjects
     are live.  We do not try to optimize those cases.  */
}

/* STMT initializes an object using a CONSTRUCTOR where one or more of the
   bytes written are dead stores.  ORIG is the bitmap of bytes stored by
   STMT.  LIVE is the bitmap of stores that are actually live.

   Attempt to rewrite STMT so that only the real or imaginary part of
   the object is actually stored.

   The most common case for getting here is a CONSTRUCTOR with no elements
   being used to zero initialize an object.  We do not try to handle other
   cases as those would force us to fully cover the object with the
   CONSTRUCTOR node except for the components that are dead.  */

static void
maybe_trim_constructor_store (ao_ref *ref, sbitmap live, gimple *stmt)
{
  tree ctor = gimple_assign_rhs1 (stmt);

  /* This is the only case we currently handle.  It actually seems to
     catch most cases of actual interest.  */
  gcc_assert (CONSTRUCTOR_NELTS (ctor) == 0);

  int head_trim = 0;
  int tail_trim = 0;
  compute_trims (ref, live, &head_trim, &tail_trim, stmt);

  /* Now we want to replace the constructor initializer
     with memset (object + head_trim, 0, size - head_trim - tail_trim).  */
  if (head_trim || tail_trim)
    {
      /* We want &lhs for the MEM_REF expression.  */
      tree lhs_addr = build_fold_addr_expr (gimple_assign_lhs (stmt));

      if (! is_gimple_min_invariant (lhs_addr))
	return;

      /* The number of bytes for the new constructor.  */
      poly_int64 ref_bytes = exact_div (ref->size, BITS_PER_UNIT);
      poly_int64 count = ref_bytes - head_trim - tail_trim;

      /* And the new type for the CONSTRUCTOR.  Essentially it's just
	 a char array large enough to cover the non-trimmed parts of
	 the original CONSTRUCTOR.  Note we want explicit bounds here
	 so that we know how many bytes to clear when expanding the
	 CONSTRUCTOR.  */
      tree type = build_array_type_nelts (char_type_node, count);

      /* Build a suitable alias type rather than using alias set zero
	 to avoid pessimizing.  */
      tree alias_type = reference_alias_ptr_type (gimple_assign_lhs (stmt));

      /* Build a MEM_REF representing the whole accessed area, starting
	 at the first byte not trimmed.  */
      tree exp = fold_build2 (MEM_REF, type, lhs_addr,
			      build_int_cst (alias_type, head_trim));

      /* Now update STMT with a new RHS and LHS.  */
      gimple_assign_set_lhs (stmt, exp);
      gimple_assign_set_rhs1 (stmt, build_constructor (type, NULL));
    }
}

/* STMT is a memcpy, memmove or memset.  Decrement the number of bytes
   copied/set by DECREMENT.  */
static void
decrement_count (gimple *stmt, int decrement)
{
  tree *countp = gimple_call_arg_ptr (stmt, 2);
  gcc_assert (TREE_CODE (*countp) == INTEGER_CST);
  *countp = wide_int_to_tree (TREE_TYPE (*countp), (TREE_INT_CST_LOW (*countp)
						    - decrement));
}

static void
increment_start_addr (gimple *stmt, tree *where, int increment)
{
  if (tree lhs = gimple_call_lhs (stmt))
    if (where == gimple_call_arg_ptr (stmt, 0))
      {
	gassign *newop = gimple_build_assign (lhs, unshare_expr (*where));
	gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
	gsi_insert_after (&gsi, newop, GSI_SAME_STMT);
	gimple_call_set_lhs (stmt, NULL_TREE);
	update_stmt (stmt);
      }

  if (TREE_CODE (*where) == SSA_NAME)
    {
      tree tem = make_ssa_name (TREE_TYPE (*where));
      gassign *newop
	= gimple_build_assign (tem, POINTER_PLUS_EXPR, *where,
			       build_int_cst (sizetype, increment));
      gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
      gsi_insert_before (&gsi, newop, GSI_SAME_STMT);
      *where = tem;
      update_stmt (stmt);
      return;
    }

  *where = build_fold_addr_expr (fold_build2 (MEM_REF, char_type_node,
					      *where,
					      build_int_cst (ptr_type_node,
							     increment)));
}

/* STMT is builtin call that writes bytes in bitmap ORIG, some bytes are dead
   (ORIG & ~NEW) and need not be stored.  Try to rewrite STMT to reduce
   the amount of data it actually writes.

   Right now we only support trimming from the head or the tail of the
   memory region.  In theory we could split the mem* call, but it's
   likely of marginal value.  */

static void
maybe_trim_memstar_call (ao_ref *ref, sbitmap live, gimple *stmt)
{
  switch (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt)))
    {
    case BUILT_IN_MEMCPY:
    case BUILT_IN_MEMMOVE:
      {
	int head_trim, tail_trim;
	compute_trims (ref, live, &head_trim, &tail_trim, stmt);

	/* Tail trimming is easy, we can just reduce the count.  */
        if (tail_trim)
	  decrement_count (stmt, tail_trim);

	/* Head trimming requires adjusting all the arguments.  */
        if (head_trim)
          {
	    tree *dst = gimple_call_arg_ptr (stmt, 0);
	    increment_start_addr (stmt, dst, head_trim);
	    tree *src = gimple_call_arg_ptr (stmt, 1);
	    increment_start_addr (stmt, src, head_trim);
	    decrement_count (stmt, head_trim);
	  }
        break;
      }

    case BUILT_IN_MEMSET:
      {
	int head_trim, tail_trim;
	compute_trims (ref, live, &head_trim, &tail_trim, stmt);

	/* Tail trimming is easy, we can just reduce the count.  */
        if (tail_trim)
	  decrement_count (stmt, tail_trim);

	/* Head trimming requires adjusting all the arguments.  */
        if (head_trim)
          {
	    tree *dst = gimple_call_arg_ptr (stmt, 0);
	    increment_start_addr (stmt, dst, head_trim);
	    decrement_count (stmt, head_trim);
	  }
	break;
      }

      default:
	break;
    }
}

/* STMT is a memory write where one or more bytes written are dead
   stores.  ORIG is the bitmap of bytes stored by STMT.  LIVE is the
   bitmap of stores that are actually live.

   Attempt to rewrite STMT so that it writes fewer memory locations.  Right
   now we only support trimming at the start or end of the memory region.
   It's not clear how much there is to be gained by trimming from the middle
   of the region.  */

static void
maybe_trim_partially_dead_store (ao_ref *ref, sbitmap live, gimple *stmt)
{
  if (is_gimple_assign (stmt)
      && TREE_CODE (gimple_assign_lhs (stmt)) != TARGET_MEM_REF)
    {
      switch (gimple_assign_rhs_code (stmt))
	{
	case CONSTRUCTOR:
	  maybe_trim_constructor_store (ref, live, stmt);
	  break;
	case COMPLEX_CST:
	  maybe_trim_complex_store (ref, live, stmt);
	  break;
	default:
	  break;
	}
    }
}

/* Return TRUE if USE_REF reads bytes from LIVE where live is
   derived from REF, a write reference.

   While this routine may modify USE_REF, it's passed by value, not
   location.  So callers do not see those modifications.  */

static bool
live_bytes_read (ao_ref use_ref, ao_ref *ref, sbitmap live)
{
  /* We have already verified that USE_REF and REF hit the same object.
     Now verify that there's actually an overlap between USE_REF and REF.  */
  HOST_WIDE_INT start, size;
  if (normalize_ref (&use_ref, ref)
      && (use_ref.offset - ref->offset).is_constant (&start)
      && use_ref.size.is_constant (&size))
    {
      /* If USE_REF covers all of REF, then it will hit one or more
	 live bytes.   This avoids useless iteration over the bitmap
	 below.  */
      if (start == 0 && known_eq (size, ref->size))
	return true;

      /* Now check if any of the remaining bits in use_ref are set in LIVE.  */
      return bitmap_bit_in_range_p (live, start / BITS_PER_UNIT,
				    (start + size - 1) / BITS_PER_UNIT);
    }
  return true;
}

/* Callback for dse_classify_store calling for_each_index.  Verify that
   indices are invariant in the loop with backedge PHI in basic-block DATA.  */

static bool
check_name (tree, tree *idx, void *data)
{
  basic_block phi_bb = (basic_block) data;
  if (TREE_CODE (*idx) == SSA_NAME
      && !SSA_NAME_IS_DEFAULT_DEF (*idx)
      && dominated_by_p (CDI_DOMINATORS, gimple_bb (SSA_NAME_DEF_STMT (*idx)),
			 phi_bb))
    return false;
  return true;
}

/* A helper of dse_optimize_stmt.
   Given a GIMPLE_ASSIGN in STMT that writes to REF, classify it
   according to downstream uses and defs.  Sets *BY_CLOBBER_P to true
   if only clobber statements influenced the classification result.
   Returns the classification.  */

static dse_store_status
dse_classify_store (ao_ref *ref, gimple *stmt,
		    bool byte_tracking_enabled, sbitmap live_bytes,
		    bool *by_clobber_p = NULL)
{
  gimple *temp;
  int cnt = 0;
  auto_bitmap visited;

  if (by_clobber_p)
    *by_clobber_p = true;

  /* Find the first dominated statement that clobbers (part of) the
     memory stmt stores to with no intermediate statement that may use
     part of the memory stmt stores.  That is, find a store that may
     prove stmt to be a dead store.  */
  temp = stmt;
  do
    {
      gimple *use_stmt;
      imm_use_iterator ui;
      bool fail = false;
      tree defvar;

      if (gimple_code (temp) == GIMPLE_PHI)
	{
	  /* If we visit this PHI by following a backedge then we have to
	     make sure ref->ref only refers to SSA names that are invariant
	     with respect to the loop represented by this PHI node.  */
	  if (dominated_by_p (CDI_DOMINATORS, gimple_bb (stmt),
			      gimple_bb (temp))
	      && !for_each_index (ref->ref ? &ref->ref : &ref->base,
				  check_name, gimple_bb (temp)))
	    return DSE_STORE_LIVE;
	  defvar = PHI_RESULT (temp);
	  bitmap_set_bit (visited, SSA_NAME_VERSION (defvar));
	}
      else
	defvar = gimple_vdef (temp);
      auto_vec<gimple *, 10> defs;
      gimple *phi_def = NULL;
      FOR_EACH_IMM_USE_STMT (use_stmt, ui, defvar)
	{
	  /* Limit stmt walking.  */
	  if (++cnt > PARAM_VALUE (PARAM_DSE_MAX_ALIAS_QUERIES_PER_STORE))
	    {
	      fail = true;
	      BREAK_FROM_IMM_USE_STMT (ui);
	    }

	  /* We have visited ourselves already so ignore STMT for the
	     purpose of chaining.  */
	  if (use_stmt == stmt)
	    ;
	  /* In simple cases we can look through PHI nodes, but we
	     have to be careful with loops and with memory references
	     containing operands that are also operands of PHI nodes.
	     See gcc.c-torture/execute/20051110-*.c.  */
	  else if (gimple_code (use_stmt) == GIMPLE_PHI)
	    {
	      /* If we already visited this PHI ignore it for further
		 processing.  */
	      if (!bitmap_bit_p (visited,
				 SSA_NAME_VERSION (PHI_RESULT (use_stmt))))
		{
		  defs.safe_push (use_stmt);
		  phi_def = use_stmt;
		}
	    }
	  /* If the statement is a use the store is not dead.  */
	  else if (ref_maybe_used_by_stmt_p (use_stmt, ref))
	    {
	      /* Handle common cases where we can easily build an ao_ref
		 structure for USE_STMT and in doing so we find that the
		 references hit non-live bytes and thus can be ignored.  */
	      if (byte_tracking_enabled
		  && is_gimple_assign (use_stmt))
		{
		  ao_ref use_ref;
		  ao_ref_init (&use_ref, gimple_assign_rhs1 (use_stmt));
		  if (valid_ao_ref_for_dse (&use_ref)
		      && use_ref.base == ref->base
		      && known_eq (use_ref.size, use_ref.max_size)
		      && !live_bytes_read (use_ref, ref, live_bytes))
		    {
		      /* If this is a store, remember it as we possibly
			 need to walk the defs uses.  */
		      if (gimple_vdef (use_stmt))
			defs.safe_push (use_stmt);
		      continue;
		    }
		}

	      fail = true;
	      BREAK_FROM_IMM_USE_STMT (ui);
	    }
	  /* If this is a store, remember it as we possibly need to walk the
	     defs uses.  */
	  else if (gimple_vdef (use_stmt))
	    defs.safe_push (use_stmt);
	}

      if (fail)
	{
	  /* STMT might be partially dead and we may be able to reduce
	     how many memory locations it stores into.  */
	  if (byte_tracking_enabled && !gimple_clobber_p (stmt))
	    return DSE_STORE_MAYBE_PARTIAL_DEAD;
	  return DSE_STORE_LIVE;
	}

      /* If we didn't find any definition this means the store is dead
         if it isn't a store to global reachable memory.  In this case
	 just pretend the stmt makes itself dead.  Otherwise fail.  */
      if (defs.is_empty ())
	{
	  if (ref_may_alias_global_p (ref))
	    return DSE_STORE_LIVE;

	  if (by_clobber_p)
	    *by_clobber_p = false;
	  return DSE_STORE_DEAD;
	}

      /* Process defs and remove those we need not process further.  */
      for (unsigned i = 0; i < defs.length ();)
	{
	  gimple *def = defs[i];
	  gimple *use_stmt;
	  use_operand_p use_p;
	  /* If the path to check starts with a kill we do not need to
	     process it further.
	     ???  With byte tracking we need only kill the bytes currently
	     live.  */
	  if (stmt_kills_ref_p (def, ref))
	    {
	      if (by_clobber_p && !gimple_clobber_p (def))
		*by_clobber_p = false;
	      defs.unordered_remove (i);
	    }
	  /* In addition to kills we can remove defs whose only use
	     is another def in defs.  That can only ever be PHIs of which
	     we track a single for simplicity reasons (we fail for multiple
	     PHIs anyways).  We can also ignore defs that feed only into
	     already visited PHIs.  */
	  else if (gimple_code (def) != GIMPLE_PHI
		   && single_imm_use (gimple_vdef (def), &use_p, &use_stmt)
		   && (use_stmt == phi_def
		       || (gimple_code (use_stmt) == GIMPLE_PHI
			   && bitmap_bit_p (visited,
					    SSA_NAME_VERSION
					      (PHI_RESULT (use_stmt))))))
	    defs.unordered_remove (i);
	  else
	    ++i;
	}

      /* If all defs kill the ref we are done.  */
      if (defs.is_empty ())
	return DSE_STORE_DEAD;
      /* If more than one def survives fail.  */
      if (defs.length () > 1)
	{
	  /* STMT might be partially dead and we may be able to reduce
	     how many memory locations it stores into.  */
	  if (byte_tracking_enabled && !gimple_clobber_p (stmt))
	    return DSE_STORE_MAYBE_PARTIAL_DEAD;
	  return DSE_STORE_LIVE;
	}
      temp = defs[0];

      /* Track partial kills.  */
      if (byte_tracking_enabled)
	{
	  clear_bytes_written_by (live_bytes, temp, ref);
	  if (bitmap_empty_p (live_bytes))
	    {
	      if (by_clobber_p && !gimple_clobber_p (temp))
		*by_clobber_p = false;
	      return DSE_STORE_DEAD;
	    }
	}
    }
  /* Continue walking until there are no more live bytes.  */
  while (1);
}


class dse_dom_walker : public dom_walker
{
public:
  dse_dom_walker (cdi_direction direction)
    : dom_walker (direction),
    m_live_bytes (PARAM_VALUE (PARAM_DSE_MAX_OBJECT_SIZE)),
    m_byte_tracking_enabled (false) {}

  virtual edge before_dom_children (basic_block);

private:
  auto_sbitmap m_live_bytes;
  bool m_byte_tracking_enabled;
  void dse_optimize_stmt (gimple_stmt_iterator *);
};

/* Delete a dead call at GSI, which is mem* call of some kind.  */
static void
delete_dead_call (gimple_stmt_iterator *gsi)
{
  gimple *stmt = gsi_stmt (*gsi);
  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "  Deleted dead call: ");
      print_gimple_stmt (dump_file, stmt, 0, dump_flags);
      fprintf (dump_file, "\n");
    }

  tree lhs = gimple_call_lhs (stmt);
  if (lhs)
    {
      tree ptr = gimple_call_arg (stmt, 0);
      gimple *new_stmt = gimple_build_assign (lhs, ptr);
      unlink_stmt_vdef (stmt);
      if (gsi_replace (gsi, new_stmt, true))
        bitmap_set_bit (need_eh_cleanup, gimple_bb (stmt)->index);
    }
  else
    {
      /* Then we need to fix the operand of the consuming stmt.  */
      unlink_stmt_vdef (stmt);

      /* Remove the dead store.  */
      if (gsi_remove (gsi, true))
	bitmap_set_bit (need_eh_cleanup, gimple_bb (stmt)->index);
      release_defs (stmt);
    }
}

/* Delete a dead store at GSI, which is a gimple assignment. */

static void
delete_dead_assignment (gimple_stmt_iterator *gsi)
{
  gimple *stmt = gsi_stmt (*gsi);
  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "  Deleted dead store: ");
      print_gimple_stmt (dump_file, stmt, 0, dump_flags);
      fprintf (dump_file, "\n");
    }

  /* Then we need to fix the operand of the consuming stmt.  */
  unlink_stmt_vdef (stmt);

  /* Remove the dead store.  */
  basic_block bb = gimple_bb (stmt);
  if (gsi_remove (gsi, true))
    bitmap_set_bit (need_eh_cleanup, bb->index);

  /* And release any SSA_NAMEs set in this statement back to the
     SSA_NAME manager.  */
  release_defs (stmt);
}

/* Attempt to eliminate dead stores in the statement referenced by BSI.

   A dead store is a store into a memory location which will later be
   overwritten by another store without any intervening loads.  In this
   case the earlier store can be deleted.

   In our SSA + virtual operand world we use immediate uses of virtual
   operands to detect dead stores.  If a store's virtual definition
   is used precisely once by a later store to the same location which
   post dominates the first store, then the first store is dead.  */

void
dse_dom_walker::dse_optimize_stmt (gimple_stmt_iterator *gsi)
{
  gimple *stmt = gsi_stmt (*gsi);

  /* If this statement has no virtual defs, then there is nothing
     to do.  */
  if (!gimple_vdef (stmt))
    return;

  /* Don't return early on *this_2(D) ={v} {CLOBBER}.  */
  if (gimple_has_volatile_ops (stmt)
      && (!gimple_clobber_p (stmt)
	  || TREE_CODE (gimple_assign_lhs (stmt)) != MEM_REF))
    return;

  ao_ref ref;
  if (!initialize_ao_ref_for_dse (stmt, &ref))
    return;

  /* We know we have virtual definitions.  We can handle assignments and
     some builtin calls.  */
  if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
    {
      switch (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt)))
	{
	  case BUILT_IN_MEMCPY:
	  case BUILT_IN_MEMMOVE:
	  case BUILT_IN_MEMSET:
	    {
	      /* Occasionally calls with an explicit length of zero
		 show up in the IL.  It's pointless to do analysis
		 on them, they're trivially dead.  */
	      tree size = gimple_call_arg (stmt, 2);
	      if (integer_zerop (size))
		{
		  delete_dead_call (gsi);
		  return;
		}

	      enum dse_store_status store_status;
	      m_byte_tracking_enabled
		= setup_live_bytes_from_ref (&ref, m_live_bytes);
	      store_status = dse_classify_store (&ref, stmt,
						 m_byte_tracking_enabled,
						 m_live_bytes);
	      if (store_status == DSE_STORE_LIVE)
		return;

	      if (store_status == DSE_STORE_MAYBE_PARTIAL_DEAD)
		{
		  maybe_trim_memstar_call (&ref, m_live_bytes, stmt);
		  return;
		}

	      if (store_status == DSE_STORE_DEAD)
		delete_dead_call (gsi);
	      return;
	    }

	  default:
	    return;
	}
    }

  if (is_gimple_assign (stmt))
    {
      bool by_clobber_p = false;

      /* Self-assignments are zombies.  */
      if (operand_equal_p (gimple_assign_rhs1 (stmt),
			   gimple_assign_lhs (stmt), 0))
	;
      else
	{
	  m_byte_tracking_enabled
	    = setup_live_bytes_from_ref (&ref, m_live_bytes);
	  enum dse_store_status store_status;
	  store_status = dse_classify_store (&ref, stmt,
					     m_byte_tracking_enabled,
					     m_live_bytes, &by_clobber_p);
	  if (store_status == DSE_STORE_LIVE)
	    return;

	  if (store_status == DSE_STORE_MAYBE_PARTIAL_DEAD)
	    {
	      maybe_trim_partially_dead_store (&ref, m_live_bytes, stmt);
	      return;
	    }
	}

      /* Now we know that use_stmt kills the LHS of stmt.  */

      /* But only remove *this_2(D) ={v} {CLOBBER} if killed by
	 another clobber stmt.  */
      if (gimple_clobber_p (stmt)
	  && !by_clobber_p)
	return;

      delete_dead_assignment (gsi);
    }
}

edge
dse_dom_walker::before_dom_children (basic_block bb)
{
  gimple_stmt_iterator gsi;

  for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi);)
    {
      dse_optimize_stmt (&gsi);
      if (gsi_end_p (gsi))
	gsi = gsi_last_bb (bb);
      else
	gsi_prev (&gsi);
    }
  return NULL;
}

namespace {

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

class pass_dse : public gimple_opt_pass
{
public:
  pass_dse (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_dse, ctxt)
  {}

  /* opt_pass methods: */
  opt_pass * clone () { return new pass_dse (m_ctxt); }
  virtual bool gate (function *) { return flag_tree_dse != 0; }
  virtual unsigned int execute (function *);

}; // class pass_dse

unsigned int
pass_dse::execute (function *fun)
{
  need_eh_cleanup = BITMAP_ALLOC (NULL);

  renumber_gimple_stmt_uids (cfun);

  /* We might consider making this a property of each pass so that it
     can be [re]computed on an as-needed basis.  Particularly since
     this pass could be seen as an extension of DCE which needs post
     dominators.  */
  calculate_dominance_info (CDI_POST_DOMINATORS);
  calculate_dominance_info (CDI_DOMINATORS);

  /* Dead store elimination is fundamentally a walk of the post-dominator
     tree and a backwards walk of statements within each block.  */
  dse_dom_walker (CDI_POST_DOMINATORS).walk (fun->cfg->x_exit_block_ptr);

  /* Removal of stores may make some EH edges dead.  Purge such edges from
     the CFG as needed.  */
  if (!bitmap_empty_p (need_eh_cleanup))
    {
      gimple_purge_all_dead_eh_edges (need_eh_cleanup);
      cleanup_tree_cfg ();
    }

  BITMAP_FREE (need_eh_cleanup);

  /* For now, just wipe the post-dominator information.  */
  free_dominance_info (CDI_POST_DOMINATORS);
  return 0;
}

} // anon namespace

gimple_opt_pass *
make_pass_dse (gcc::context *ctxt)
{
  return new pass_dse (ctxt);
}
