/* Dead code elimination pass for the GNU compiler.
   Copyright (C) 2002-2022 Free Software Foundation, Inc.
   Contributed by Ben Elliston <bje@redhat.com>
   and Andrew MacLeod <amacleod@redhat.com>
   Adapted to use control dependence by Steven Bosscher, SUSE Labs.

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

/* Dead code elimination.

   References:

     Building an Optimizing Compiler,
     Robert Morgan, Butterworth-Heinemann, 1998, Section 8.9.

     Advanced Compiler Design and Implementation,
     Steven Muchnick, Morgan Kaufmann, 1997, Section 18.10.

   Dead-code elimination is the removal of statements which have no
   impact on the program's output.  "Dead statements" have no impact
   on the program's output, while "necessary statements" may have
   impact on the output.

   The algorithm consists of three phases:
   1. Marking as necessary all statements known to be necessary,
      e.g. most function calls, writing a value to memory, etc;
   2. Propagating necessary statements, e.g., the statements
      giving values to operands in necessary statements; and
   3. Removing dead statements.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "cfghooks.h"
#include "tree-pass.h"
#include "ssa.h"
#include "gimple-pretty-print.h"
#include "fold-const.h"
#include "calls.h"
#include "cfganal.h"
#include "tree-eh.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "tree-cfg.h"
#include "tree-ssa-loop-niter.h"
#include "tree-into-ssa.h"
#include "tree-dfa.h"
#include "cfgloop.h"
#include "tree-scalar-evolution.h"
#include "tree-ssa-propagate.h"
#include "gimple-fold.h"
#include "tree-ssa.h"

static struct stmt_stats
{
  int total;
  int total_phis;
  int removed;
  int removed_phis;
} stats;

#define STMT_NECESSARY GF_PLF_1

static vec<gimple *> worklist;

/* Vector indicating an SSA name has already been processed and marked
   as necessary.  */
static sbitmap processed;

/* Vector indicating that the last statement of a basic block has already
   been marked as necessary.  */
static sbitmap last_stmt_necessary;

/* Vector indicating that BB contains statements that are live.  */
static sbitmap bb_contains_live_stmts;

/* Before we can determine whether a control branch is dead, we need to
   compute which blocks are control dependent on which edges.

   We expect each block to be control dependent on very few edges so we
   use a bitmap for each block recording its edges.  An array holds the
   bitmap.  The Ith bit in the bitmap is set if that block is dependent
   on the Ith edge.  */
static control_dependences *cd;

/* Vector indicating that a basic block has already had all the edges
   processed that it is control dependent on.  */
static sbitmap visited_control_parents;

/* TRUE if this pass alters the CFG (by removing control statements).
   FALSE otherwise.

   If this pass alters the CFG, then it will arrange for the dominators
   to be recomputed.  */
static bool cfg_altered;

/* When non-NULL holds map from basic block index into the postorder.  */
static int *bb_postorder;


/* True if we should treat any stmt with a vdef as necessary.  */

static inline bool
keep_all_vdefs_p ()
{
  return optimize_debug;
}

/* If STMT is not already marked necessary, mark it, and add it to the
   worklist if ADD_TO_WORKLIST is true.  */

static inline void
mark_stmt_necessary (gimple *stmt, bool add_to_worklist)
{
  gcc_assert (stmt);

  if (gimple_plf (stmt, STMT_NECESSARY))
    return;

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Marking useful stmt: ");
      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
      fprintf (dump_file, "\n");
    }

  gimple_set_plf (stmt, STMT_NECESSARY, true);
  if (add_to_worklist)
    worklist.safe_push (stmt);
  if (add_to_worklist && bb_contains_live_stmts && !is_gimple_debug (stmt))
    bitmap_set_bit (bb_contains_live_stmts, gimple_bb (stmt)->index);
}


/* Mark the statement defining operand OP as necessary.  */

static inline void
mark_operand_necessary (tree op)
{
  gimple *stmt;
  int ver;

  gcc_assert (op);

  ver = SSA_NAME_VERSION (op);
  if (bitmap_bit_p (processed, ver))
    {
      stmt = SSA_NAME_DEF_STMT (op);
      gcc_assert (gimple_nop_p (stmt)
		  || gimple_plf (stmt, STMT_NECESSARY));
      return;
    }
  bitmap_set_bit (processed, ver);

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

  if (gimple_plf (stmt, STMT_NECESSARY) || gimple_nop_p (stmt))
    return;

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "marking necessary through ");
      print_generic_expr (dump_file, op);
      fprintf (dump_file, " stmt ");
      print_gimple_stmt (dump_file, stmt, 0);
    }

  gimple_set_plf (stmt, STMT_NECESSARY, true);
  if (bb_contains_live_stmts)
    bitmap_set_bit (bb_contains_live_stmts, gimple_bb (stmt)->index);
  worklist.safe_push (stmt);
}


/* Mark STMT as necessary if it obviously is.  Add it to the worklist if
   it can make other statements necessary.

   If AGGRESSIVE is false, control statements are conservatively marked as
   necessary.  */

static void
mark_stmt_if_obviously_necessary (gimple *stmt, bool aggressive)
{
  /* Statements that are implicitly live.  Most function calls, asm
     and return statements are required.  Labels and GIMPLE_BIND nodes
     are kept because they are control flow, and we have no way of
     knowing whether they can be removed.  DCE can eliminate all the
     other statements in a block, and CFG can then remove the block
     and labels.  */
  switch (gimple_code (stmt))
    {
    case GIMPLE_PREDICT:
    case GIMPLE_LABEL:
      mark_stmt_necessary (stmt, false);
      return;

    case GIMPLE_ASM:
    case GIMPLE_RESX:
    case GIMPLE_RETURN:
      mark_stmt_necessary (stmt, true);
      return;

    case GIMPLE_CALL:
      {
	tree callee = gimple_call_fndecl (stmt);
	if (callee != NULL_TREE
	    && fndecl_built_in_p (callee, BUILT_IN_NORMAL))
	  switch (DECL_FUNCTION_CODE (callee))
	    {
	    case BUILT_IN_MALLOC:
	    case BUILT_IN_ALIGNED_ALLOC:
	    case BUILT_IN_CALLOC:
	    CASE_BUILT_IN_ALLOCA:
	    case BUILT_IN_STRDUP:
	    case BUILT_IN_STRNDUP:
	    case BUILT_IN_GOMP_ALLOC:
	      return;

	    default:;
	    }

	if (callee != NULL_TREE
	    && flag_allocation_dce
	    && DECL_IS_REPLACEABLE_OPERATOR_NEW_P (callee))
	  return;

	/* IFN_GOACC_LOOP calls are necessary in that they are used to
	   represent parameter (i.e. step, bound) of a lowered OpenACC
	   partitioned loop.  But this kind of partitioned loop might not
	   survive from aggressive loop removal for it has loop exit and
	   is assumed to be finite.  Therefore, we need to explicitly mark
	   these calls. (An example is libgomp.oacc-c-c++-common/pr84955.c) */
	if (gimple_call_internal_p (stmt, IFN_GOACC_LOOP))
	  {
	    mark_stmt_necessary (stmt, true);
	    return;
	  }
	break;
      }

    case GIMPLE_DEBUG:
      /* Debug temps without a value are not useful.  ??? If we could
	 easily locate the debug temp bind stmt for a use thereof,
	 would could refrain from marking all debug temps here, and
	 mark them only if they're used.  */
      if (gimple_debug_nonbind_marker_p (stmt)
	  || !gimple_debug_bind_p (stmt)
	  || gimple_debug_bind_has_value_p (stmt)
	  || TREE_CODE (gimple_debug_bind_get_var (stmt)) != DEBUG_EXPR_DECL)
	mark_stmt_necessary (stmt, false);
      return;

    case GIMPLE_GOTO:
      gcc_assert (!simple_goto_p (stmt));
      mark_stmt_necessary (stmt, true);
      return;

    case GIMPLE_COND:
      gcc_assert (EDGE_COUNT (gimple_bb (stmt)->succs) == 2);
      /* Fall through.  */

    case GIMPLE_SWITCH:
      if (! aggressive)
	mark_stmt_necessary (stmt, true);
      break;

    case GIMPLE_ASSIGN:
      /* Mark indirect CLOBBERs to be lazily removed if their SSA operands
	 do not prevail.  That also makes control flow leading to them
	 not necessary in aggressive mode.  */
      if (gimple_clobber_p (stmt) && !zero_ssa_operands (stmt, SSA_OP_USE))
	return;
      break;

    default:
      break;
    }

  /* If the statement has volatile operands, it needs to be preserved.
     Same for statements that can alter control flow in unpredictable
     ways.  */
  if (gimple_has_side_effects (stmt) || is_ctrl_altering_stmt (stmt))
    {
      mark_stmt_necessary (stmt, true);
      return;
    }

  /* If a statement could throw, it can be deemed necessary unless we
     are allowed to remove dead EH.  Test this after checking for
     new/delete operators since we always elide their EH.  */
  if (!cfun->can_delete_dead_exceptions
      && stmt_could_throw_p (cfun, stmt))
    {
      mark_stmt_necessary (stmt, true);
      return;
    }

  if ((gimple_vdef (stmt) && keep_all_vdefs_p ())
      || stmt_may_clobber_global_p (stmt, false))
    {
      mark_stmt_necessary (stmt, true);
      return;
    }

  return;
}


/* Mark the last statement of BB as necessary.  */

static void
mark_last_stmt_necessary (basic_block bb)
{
  gimple *stmt = last_stmt (bb);

  bitmap_set_bit (last_stmt_necessary, bb->index);
  bitmap_set_bit (bb_contains_live_stmts, bb->index);

  /* We actually mark the statement only if it is a control statement.  */
  if (stmt && is_ctrl_stmt (stmt))
    mark_stmt_necessary (stmt, true);
}


/* Mark control dependent edges of BB as necessary.  We have to do this only
   once for each basic block so we set the appropriate bit after we're done.

   When IGNORE_SELF is true, ignore BB in the list of control dependences.  */

static void
mark_control_dependent_edges_necessary (basic_block bb, bool ignore_self)
{
  bitmap_iterator bi;
  unsigned edge_number;
  bool skipped = false;

  gcc_assert (bb != EXIT_BLOCK_PTR_FOR_FN (cfun));

  if (bb == ENTRY_BLOCK_PTR_FOR_FN (cfun))
    return;

  EXECUTE_IF_SET_IN_BITMAP (cd->get_edges_dependent_on (bb->index),
			    0, edge_number, bi)
    {
      basic_block cd_bb = cd->get_edge_src (edge_number);

      if (ignore_self && cd_bb == bb)
	{
	  skipped = true;
	  continue;
	}

      if (!bitmap_bit_p (last_stmt_necessary, cd_bb->index))
	mark_last_stmt_necessary (cd_bb);
    }

  if (!skipped)
    bitmap_set_bit (visited_control_parents, bb->index);
}


/* Find obviously necessary statements.  These are things like most function
   calls, and stores to file level variables.

   If EL is NULL, control statements are conservatively marked as
   necessary.  Otherwise it contains the list of edges used by control
   dependence analysis.  */

static void
find_obviously_necessary_stmts (bool aggressive)
{
  basic_block bb;
  gimple_stmt_iterator gsi;
  edge e;
  gimple *phi, *stmt;
  int flags;

  FOR_EACH_BB_FN (bb, cfun)
    {
      /* PHI nodes are never inherently necessary.  */
      for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
	{
	  phi = gsi_stmt (gsi);
	  gimple_set_plf (phi, STMT_NECESSARY, false);
	}

      /* Check all statements in the block.  */
      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
	{
	  stmt = gsi_stmt (gsi);
	  gimple_set_plf (stmt, STMT_NECESSARY, false);
	  mark_stmt_if_obviously_necessary (stmt, aggressive);
	}
    }

  /* Pure and const functions are finite and thus have no infinite loops in
     them.  */
  flags = flags_from_decl_or_type (current_function_decl);
  if ((flags & (ECF_CONST|ECF_PURE)) && !(flags & ECF_LOOPING_CONST_OR_PURE))
    return;

  /* Prevent the empty possibly infinite loops from being removed.  This is
     needed to make the logic in remove_dead_stmt work to identify the
     correct edge to keep when removing a controlling condition.  */
  if (aggressive)
    {
      if (mark_irreducible_loops ())
	FOR_EACH_BB_FN (bb, cfun)
	  {
	    edge_iterator ei;
	    FOR_EACH_EDGE (e, ei, bb->succs)
	      if ((e->flags & EDGE_DFS_BACK)
		  && (e->flags & EDGE_IRREDUCIBLE_LOOP))
		{
	          if (dump_file)
		    fprintf (dump_file, "Marking back edge of irreducible "
			     "loop %i->%i\n", e->src->index, e->dest->index);
		  mark_control_dependent_edges_necessary (e->dest, false);
		}
	  }

      for (auto loop : loops_list (cfun, 0))
	/* For loops without an exit do not mark any condition.  */
	if (loop->exits->next->e && !finite_loop_p (loop))
	  {
	    if (dump_file)
	      fprintf (dump_file, "cannot prove finiteness of loop %i\n",
		       loop->num);
	    mark_control_dependent_edges_necessary (loop->latch, false);
	  }
    }
}


/* Return true if REF is based on an aliased base, otherwise false.  */

static bool
ref_may_be_aliased (tree ref)
{
  gcc_assert (TREE_CODE (ref) != WITH_SIZE_EXPR);
  while (handled_component_p (ref))
    ref = TREE_OPERAND (ref, 0);
  if ((TREE_CODE (ref) == MEM_REF || TREE_CODE (ref) == TARGET_MEM_REF)
      && TREE_CODE (TREE_OPERAND (ref, 0)) == ADDR_EXPR)
    ref = TREE_OPERAND (TREE_OPERAND (ref, 0), 0);
  return !(DECL_P (ref)
	   && !may_be_aliased (ref));
}

static bitmap visited = NULL;
static unsigned int longest_chain = 0;
static unsigned int total_chain = 0;
static unsigned int nr_walks = 0;
static bool chain_ovfl = false;

/* Worker for the walker that marks reaching definitions of REF,
   which is based on a non-aliased decl, necessary.  It returns
   true whenever the defining statement of the current VDEF is
   a kill for REF, as no dominating may-defs are necessary for REF
   anymore.  DATA points to the basic-block that contains the
   stmt that refers to REF.  */

static bool
mark_aliased_reaching_defs_necessary_1 (ao_ref *ref, tree vdef, void *data)
{
  gimple *def_stmt = SSA_NAME_DEF_STMT (vdef);

  /* All stmts we visit are necessary.  */
  if (! gimple_clobber_p (def_stmt))
    mark_operand_necessary (vdef);

  /* If the stmt lhs kills ref, then we can stop walking.  */
  if (gimple_has_lhs (def_stmt)
      && TREE_CODE (gimple_get_lhs (def_stmt)) != SSA_NAME
      /* The assignment is not necessarily carried out if it can throw
         and we can catch it in the current function where we could inspect
	 the previous value.
         ???  We only need to care about the RHS throwing.  For aggregate
	 assignments or similar calls and non-call exceptions the LHS
	 might throw as well.  */
      && !stmt_can_throw_internal (cfun, def_stmt))
    {
      tree base, lhs = gimple_get_lhs (def_stmt);
      poly_int64 size, offset, max_size;
      bool reverse;
      ao_ref_base (ref);
      base
	= get_ref_base_and_extent (lhs, &offset, &size, &max_size, &reverse);
      /* We can get MEM[symbol: sZ, index: D.8862_1] here,
	 so base == refd->base does not always hold.  */
      if (base == ref->base)
	{
	  /* For a must-alias check we need to be able to constrain
	     the accesses properly.  */
	  if (known_eq (size, max_size)
	      && known_subrange_p (ref->offset, ref->max_size, offset, size))
	    return true;
	  /* Or they need to be exactly the same.  */
	  else if (ref->ref
		   /* Make sure there is no induction variable involved
		      in the references (gcc.c-torture/execute/pr42142.c).
		      The simplest way is to check if the kill dominates
		      the use.  */
		   /* But when both are in the same block we cannot
		      easily tell whether we came from a backedge
		      unless we decide to compute stmt UIDs
		      (see PR58246).  */
		   && (basic_block) data != gimple_bb (def_stmt)
		   && dominated_by_p (CDI_DOMINATORS, (basic_block) data,
				      gimple_bb (def_stmt))
		   && operand_equal_p (ref->ref, lhs, 0))
	    return true;
	}
    }

  /* Otherwise keep walking.  */
  return false;
}

static void
mark_aliased_reaching_defs_necessary (gimple *stmt, tree ref)
{
  /* Should have been caught before calling this function.  */
  gcc_checking_assert (!keep_all_vdefs_p ());

  unsigned int chain;
  ao_ref refd;
  gcc_assert (!chain_ovfl);
  ao_ref_init (&refd, ref);
  chain = walk_aliased_vdefs (&refd, gimple_vuse (stmt),
			      mark_aliased_reaching_defs_necessary_1,
			      gimple_bb (stmt), NULL);
  if (chain > longest_chain)
    longest_chain = chain;
  total_chain += chain;
  nr_walks++;
}

/* Worker for the walker that marks reaching definitions of REF, which
   is not based on a non-aliased decl.  For simplicity we need to end
   up marking all may-defs necessary that are not based on a non-aliased
   decl.  The only job of this walker is to skip may-defs based on
   a non-aliased decl.  */

static bool
mark_all_reaching_defs_necessary_1 (ao_ref *ref ATTRIBUTE_UNUSED,
				    tree vdef, void *data ATTRIBUTE_UNUSED)
{
  gimple *def_stmt = SSA_NAME_DEF_STMT (vdef);

  /* We have to skip already visited (and thus necessary) statements
     to make the chaining work after we dropped back to simple mode.  */
  if (chain_ovfl
      && bitmap_bit_p (processed, SSA_NAME_VERSION (vdef)))
    {
      gcc_assert (gimple_nop_p (def_stmt)
		  || gimple_plf (def_stmt, STMT_NECESSARY));
      return false;
    }

  /* We want to skip stores to non-aliased variables.  */
  if (!chain_ovfl
      && gimple_assign_single_p (def_stmt))
    {
      tree lhs = gimple_assign_lhs (def_stmt);
      if (!ref_may_be_aliased (lhs))
	return false;
    }

  /* We want to skip statments that do not constitute stores but have
     a virtual definition.  */
  if (gcall *call = dyn_cast <gcall *> (def_stmt))
    {
      tree callee = gimple_call_fndecl (call);
      if (callee != NULL_TREE
	  && fndecl_built_in_p (callee, BUILT_IN_NORMAL))
	switch (DECL_FUNCTION_CODE (callee))
	  {
	  case BUILT_IN_MALLOC:
	  case BUILT_IN_ALIGNED_ALLOC:
	  case BUILT_IN_CALLOC:
	  CASE_BUILT_IN_ALLOCA:
	  case BUILT_IN_FREE:
	  case BUILT_IN_GOMP_ALLOC:
	  case BUILT_IN_GOMP_FREE:
	    return false;

	  default:;
	  }

      if (callee != NULL_TREE
	  && (DECL_IS_REPLACEABLE_OPERATOR_NEW_P (callee)
	      || DECL_IS_OPERATOR_DELETE_P (callee))
	  && gimple_call_from_new_or_delete (call))
	return false;
    }

  if (! gimple_clobber_p (def_stmt))
    mark_operand_necessary (vdef);

  return false;
}

static void
mark_all_reaching_defs_necessary (gimple *stmt)
{
  /* Should have been caught before calling this function.  */
  gcc_checking_assert (!keep_all_vdefs_p ());
  walk_aliased_vdefs (NULL, gimple_vuse (stmt),
		      mark_all_reaching_defs_necessary_1, NULL, &visited);
}

/* Return true for PHI nodes with one or identical arguments
   can be removed.  */
static bool
degenerate_phi_p (gimple *phi)
{
  unsigned int i;
  tree op = gimple_phi_arg_def (phi, 0);
  for (i = 1; i < gimple_phi_num_args (phi); i++)
    if (gimple_phi_arg_def (phi, i) != op)
      return false;
  return true;
}

/* Return that NEW_CALL and DELETE_CALL are a valid pair of new
   and delete  operators.  */

static bool
valid_new_delete_pair_p (gimple *new_call, gimple *delete_call)
{
  tree new_asm = DECL_ASSEMBLER_NAME (gimple_call_fndecl (new_call));
  tree delete_asm = DECL_ASSEMBLER_NAME (gimple_call_fndecl (delete_call));
  return valid_new_delete_pair_p (new_asm, delete_asm);
}

/* Propagate necessity using the operands of necessary statements.
   Process the uses on each statement in the worklist, and add all
   feeding statements which contribute to the calculation of this
   value to the worklist.

   In conservative mode, EL is NULL.  */

static void
propagate_necessity (bool aggressive)
{
  gimple *stmt;

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

  while (worklist.length () > 0)
    {
      /* Take STMT from worklist.  */
      stmt = worklist.pop ();

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

      if (aggressive)
	{
	  /* Mark the last statement of the basic blocks on which the block
	     containing STMT is control dependent, but only if we haven't
	     already done so.  */
	  basic_block bb = gimple_bb (stmt);
	  if (bb != ENTRY_BLOCK_PTR_FOR_FN (cfun)
	      && !bitmap_bit_p (visited_control_parents, bb->index))
	    mark_control_dependent_edges_necessary (bb, false);
	}

      if (gimple_code (stmt) == GIMPLE_PHI
	  /* We do not process virtual PHI nodes nor do we track their
	     necessity.  */
	  && !virtual_operand_p (gimple_phi_result (stmt)))
	{
	  /* PHI nodes are somewhat special in that each PHI alternative has
	     data and control dependencies.  All the statements feeding the
	     PHI node's arguments are always necessary.  In aggressive mode,
	     we also consider the control dependent edges leading to the
	     predecessor block associated with each PHI alternative as
	     necessary.  */
	  gphi *phi = as_a <gphi *> (stmt);
	  size_t k;

	  for (k = 0; k < gimple_phi_num_args (stmt); k++)
            {
	      tree arg = PHI_ARG_DEF (stmt, k);
	      if (TREE_CODE (arg) == SSA_NAME)
		mark_operand_necessary (arg);
	    }

	  /* For PHI operands it matters from where the control flow arrives
	     to the BB.  Consider the following example:

	     a=exp1;
	     b=exp2;
	     if (test)
		;
	     else
		;
	     c=PHI(a,b)

	     We need to mark control dependence of the empty basic blocks, since they
	     contains computation of PHI operands.

	     Doing so is too restrictive in the case the predecestor block is in
	     the loop. Consider:

	      if (b)
		{
		  int i;
		  for (i = 0; i<1000; ++i)
		    ;
		  j = 0;
		}
	      return j;

	     There is PHI for J in the BB containing return statement.
	     In this case the control dependence of predecestor block (that is
	     within the empty loop) also contains the block determining number
	     of iterations of the block that would prevent removing of empty
	     loop in this case.

	     This scenario can be avoided by splitting critical edges.
	     To save the critical edge splitting pass we identify how the control
	     dependence would look like if the edge was split.

	     Consider the modified CFG created from current CFG by splitting
	     edge B->C.  In the postdominance tree of modified CFG, C' is
	     always child of C.  There are two cases how chlids of C' can look
	     like:

		1) C' is leaf

		   In this case the only basic block C' is control dependent on is B.

		2) C' has single child that is B

		   In this case control dependence of C' is same as control
		   dependence of B in original CFG except for block B itself.
		   (since C' postdominate B in modified CFG)

	     Now how to decide what case happens?  There are two basic options:

		a) C postdominate B.  Then C immediately postdominate B and
		   case 2 happens iff there is no other way from B to C except
		   the edge B->C.

		   There is other way from B to C iff there is succesor of B that
		   is not postdominated by B.  Testing this condition is somewhat
		   expensive, because we need to iterate all succesors of B.
		   We are safe to assume that this does not happen: we will mark B
		   as needed when processing the other path from B to C that is
		   conrol dependent on B and marking control dependencies of B
		   itself is harmless because they will be processed anyway after
		   processing control statement in B.

		b) C does not postdominate B.  Always case 1 happens since there is
		   path from C to exit that does not go through B and thus also C'.  */

	  if (aggressive && !degenerate_phi_p (stmt))
	    {
	      for (k = 0; k < gimple_phi_num_args (stmt); k++)
		{
		  basic_block arg_bb = gimple_phi_arg_edge (phi, k)->src;

		  if (gimple_bb (stmt)
		      != get_immediate_dominator (CDI_POST_DOMINATORS, arg_bb))
		    {
		      if (!bitmap_bit_p (last_stmt_necessary, arg_bb->index))
			mark_last_stmt_necessary (arg_bb);
		    }
		  else if (arg_bb != ENTRY_BLOCK_PTR_FOR_FN (cfun)
		           && !bitmap_bit_p (visited_control_parents,
					 arg_bb->index))
		    mark_control_dependent_edges_necessary (arg_bb, true);
		}
	    }
	}
      else
	{
	  /* Propagate through the operands.  Examine all the USE, VUSE and
	     VDEF operands in this statement.  Mark all the statements
	     which feed this statement's uses as necessary.  */
	  ssa_op_iter iter;
	  tree use;

	  /* If this is a call to free which is directly fed by an
	     allocation function do not mark that necessary through
	     processing the argument.  */
	  bool is_delete_operator
	    = (is_gimple_call (stmt)
	       && gimple_call_from_new_or_delete (as_a <gcall *> (stmt))
	       && gimple_call_operator_delete_p (as_a <gcall *> (stmt)));
	  if (is_delete_operator
	      || gimple_call_builtin_p (stmt, BUILT_IN_FREE)
	      || gimple_call_builtin_p (stmt, BUILT_IN_GOMP_FREE))
	    {
	      tree ptr = gimple_call_arg (stmt, 0);
	      gcall *def_stmt;
	      tree def_callee;
	      /* If the pointer we free is defined by an allocation
		 function do not add the call to the worklist.  */
	      if (TREE_CODE (ptr) == SSA_NAME
		  && (def_stmt = dyn_cast <gcall *> (SSA_NAME_DEF_STMT (ptr)))
		  && (def_callee = gimple_call_fndecl (def_stmt))
		  && ((DECL_BUILT_IN_CLASS (def_callee) == BUILT_IN_NORMAL
		       && (DECL_FUNCTION_CODE (def_callee) == BUILT_IN_ALIGNED_ALLOC
			   || DECL_FUNCTION_CODE (def_callee) == BUILT_IN_MALLOC
			   || DECL_FUNCTION_CODE (def_callee) == BUILT_IN_CALLOC
			   || DECL_FUNCTION_CODE (def_callee) == BUILT_IN_GOMP_ALLOC))
		      || (DECL_IS_REPLACEABLE_OPERATOR_NEW_P (def_callee)
			  && gimple_call_from_new_or_delete (def_stmt))))
		{
		  if (is_delete_operator
		      && !valid_new_delete_pair_p (def_stmt, stmt))
		    mark_operand_necessary (gimple_call_arg (stmt, 0));

		  /* Delete operators can have alignment and (or) size
		     as next arguments.  When being a SSA_NAME, they
		     must be marked as necessary.  Similarly GOMP_free.  */
		  if (gimple_call_num_args (stmt) >= 2)
		    for (unsigned i = 1; i < gimple_call_num_args (stmt);
			 i++)
		      {
			tree arg = gimple_call_arg (stmt, i);
			if (TREE_CODE (arg) == SSA_NAME)
			  mark_operand_necessary (arg);
		      }

		  continue;
		}
	    }

	  FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
	    mark_operand_necessary (use);

	  use = gimple_vuse (stmt);
	  if (!use)
	    continue;

	  /* No need to search for vdefs if we intrinsicly keep them all.  */
	  if (keep_all_vdefs_p ())
	    continue;

	  /* If we dropped to simple mode make all immediately
	     reachable definitions necessary.  */
	  if (chain_ovfl)
	    {
	      mark_all_reaching_defs_necessary (stmt);
	      continue;
	    }

	  /* For statements that may load from memory (have a VUSE) we
	     have to mark all reaching (may-)definitions as necessary.
	     We partition this task into two cases:
	      1) explicit loads based on decls that are not aliased
	      2) implicit loads (like calls) and explicit loads not
	         based on decls that are not aliased (like indirect
		 references or loads from globals)
	     For 1) we mark all reaching may-defs as necessary, stopping
	     at dominating kills.  For 2) we want to mark all dominating
	     references necessary, but non-aliased ones which we handle
	     in 1).  By keeping a global visited bitmap for references
	     we walk for 2) we avoid quadratic behavior for those.  */

	  if (gcall *call = dyn_cast <gcall *> (stmt))
	    {
	      tree callee = gimple_call_fndecl (call);
	      unsigned i;

	      /* Calls to functions that are merely acting as barriers
		 or that only store to memory do not make any previous
		 stores necessary.  */
	      if (callee != NULL_TREE
		  && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
		  && (DECL_FUNCTION_CODE (callee) == BUILT_IN_MEMSET
		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_MEMSET_CHK
		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_MALLOC
		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_ALIGNED_ALLOC
		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_CALLOC
		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_FREE
		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_VA_END
		      || ALLOCA_FUNCTION_CODE_P (DECL_FUNCTION_CODE (callee))
		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_SAVE
		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_RESTORE
		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_ASSUME_ALIGNED))
		continue;

	      if (callee != NULL_TREE
		  && (DECL_IS_REPLACEABLE_OPERATOR_NEW_P (callee)
		      || DECL_IS_OPERATOR_DELETE_P (callee))
		  && gimple_call_from_new_or_delete (call))
		continue;

	      /* Calls implicitly load from memory, their arguments
	         in addition may explicitly perform memory loads.  */
	      mark_all_reaching_defs_necessary (call);
	      for (i = 0; i < gimple_call_num_args (call); ++i)
		{
		  tree arg = gimple_call_arg (call, i);
		  if (TREE_CODE (arg) == SSA_NAME
		      || is_gimple_min_invariant (arg))
		    continue;
		  if (TREE_CODE (arg) == WITH_SIZE_EXPR)
		    arg = TREE_OPERAND (arg, 0);
		  if (!ref_may_be_aliased (arg))
		    mark_aliased_reaching_defs_necessary (call, arg);
		}
	    }
	  else if (gimple_assign_single_p (stmt))
	    {
	      tree rhs;
	      /* If this is a load mark things necessary.  */
	      rhs = gimple_assign_rhs1 (stmt);
	      if (TREE_CODE (rhs) != SSA_NAME
		  && !is_gimple_min_invariant (rhs)
		  && TREE_CODE (rhs) != CONSTRUCTOR)
		{
		  if (!ref_may_be_aliased (rhs))
		    mark_aliased_reaching_defs_necessary (stmt, rhs);
		  else
		    mark_all_reaching_defs_necessary (stmt);
		}
	    }
	  else if (greturn *return_stmt = dyn_cast <greturn *> (stmt))
	    {
	      tree rhs = gimple_return_retval (return_stmt);
	      /* A return statement may perform a load.  */
	      if (rhs
		  && TREE_CODE (rhs) != SSA_NAME
		  && !is_gimple_min_invariant (rhs)
		  && TREE_CODE (rhs) != CONSTRUCTOR)
		{
		  if (!ref_may_be_aliased (rhs))
		    mark_aliased_reaching_defs_necessary (stmt, rhs);
		  else
		    mark_all_reaching_defs_necessary (stmt);
		}
	    }
	  else if (gasm *asm_stmt = dyn_cast <gasm *> (stmt))
	    {
	      unsigned i;
	      mark_all_reaching_defs_necessary (stmt);
	      /* Inputs may perform loads.  */
	      for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
		{
		  tree op = TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
		  if (TREE_CODE (op) != SSA_NAME
		      && !is_gimple_min_invariant (op)
		      && TREE_CODE (op) != CONSTRUCTOR
		      && !ref_may_be_aliased (op))
		    mark_aliased_reaching_defs_necessary (stmt, op);
		}
	    }
	  else if (gimple_code (stmt) == GIMPLE_TRANSACTION)
	    {
	      /* The beginning of a transaction is a memory barrier.  */
	      /* ??? If we were really cool, we'd only be a barrier
		 for the memories touched within the transaction.  */
	      mark_all_reaching_defs_necessary (stmt);
	    }
	  else
	    gcc_unreachable ();

	  /* If we over-used our alias oracle budget drop to simple
	     mode.  The cost metric allows quadratic behavior
	     (number of uses times number of may-defs queries) up to
	     a constant maximal number of queries and after that falls back to
	     super-linear complexity.  */
	  if (/* Constant but quadratic for small functions.  */
	      total_chain > 128 * 128
	      /* Linear in the number of may-defs.  */
	      && total_chain > 32 * longest_chain
	      /* Linear in the number of uses.  */
	      && total_chain > nr_walks * 32)
	    {
	      chain_ovfl = true;
	      if (visited)
		bitmap_clear (visited);
	    }
	}
    }
}

/* Remove dead PHI nodes from block BB.  */

static bool
remove_dead_phis (basic_block bb)
{
  bool something_changed = false;
  gphi *phi;
  gphi_iterator gsi;

  for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi);)
    {
      stats.total_phis++;
      phi = gsi.phi ();

      /* We do not track necessity of virtual PHI nodes.  Instead do
         very simple dead PHI removal here.  */
      if (virtual_operand_p (gimple_phi_result (phi)))
	{
	  /* Virtual PHI nodes with one or identical arguments
	     can be removed.  */
	  if (!loops_state_satisfies_p (LOOP_CLOSED_SSA)
	      && degenerate_phi_p (phi))
	    {
	      tree vdef = gimple_phi_result (phi);
	      tree vuse = gimple_phi_arg_def (phi, 0);

	      use_operand_p use_p;
	      imm_use_iterator iter;
	      gimple *use_stmt;
	      FOR_EACH_IMM_USE_STMT (use_stmt, iter, vdef)
		FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
		  SET_USE (use_p, vuse);
	      if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (vdef)
	          && TREE_CODE (vuse) == SSA_NAME)
		SSA_NAME_OCCURS_IN_ABNORMAL_PHI (vuse) = 1;
	    }
	  else
	    gimple_set_plf (phi, STMT_NECESSARY, true);
	}

      if (!gimple_plf (phi, STMT_NECESSARY))
	{
	  something_changed = true;
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "Deleting : ");
	      print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
	      fprintf (dump_file, "\n");
	    }

	  remove_phi_node (&gsi, true);
	  stats.removed_phis++;
	  continue;
	}

      gsi_next (&gsi);
    }
  return something_changed;
}


/* Remove dead statement pointed to by iterator I.  Receives the basic block BB
   containing I so that we don't have to look it up.  */

static void
remove_dead_stmt (gimple_stmt_iterator *i, basic_block bb,
		  vec<edge> &to_remove_edges)
{
  gimple *stmt = gsi_stmt (*i);

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

  stats.removed++;

  /* If we have determined that a conditional branch statement contributes
     nothing to the program, then we not only remove it, but we need to update
     the CFG.  We can chose any of edges out of BB as long as we are sure to not
     close infinite loops.  This is done by always choosing the edge closer to
     exit in inverted_post_order_compute order.  */
  if (is_ctrl_stmt (stmt))
    {
      edge_iterator ei;
      edge e = NULL, e2;

      /* See if there is only one non-abnormal edge.  */
      if (single_succ_p (bb))
        e = single_succ_edge (bb);
      /* Otherwise chose one that is closer to bb with live statement in it.
         To be able to chose one, we compute inverted post order starting from
	 all BBs with live statements.  */
      if (!e)
	{
	  if (!bb_postorder)
	    {
	      auto_vec<int, 20> postorder;
		 inverted_post_order_compute (&postorder,
					      &bb_contains_live_stmts);
	      bb_postorder = XNEWVEC (int, last_basic_block_for_fn (cfun));
	      for (unsigned int i = 0; i < postorder.length (); ++i)
		 bb_postorder[postorder[i]] = i;
	    }
          FOR_EACH_EDGE (e2, ei, bb->succs)
	    if (!e || e2->dest == EXIT_BLOCK_PTR_FOR_FN (cfun)
		|| bb_postorder [e->dest->index]
		   < bb_postorder [e2->dest->index])
	      e = e2;
	}
      gcc_assert (e);
      e->probability = profile_probability::always ();

      /* The edge is no longer associated with a conditional, so it does
	 not have TRUE/FALSE flags.
	 We are also safe to drop EH/ABNORMAL flags and turn them into
	 normal control flow, because we know that all the destinations (including
	 those odd edges) are equivalent for program execution.  */
      e->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE | EDGE_EH | EDGE_ABNORMAL);

      /* The lone outgoing edge from BB will be a fallthru edge.  */
      e->flags |= EDGE_FALLTHRU;

      /* Remove the remaining outgoing edges.  */
      FOR_EACH_EDGE (e2, ei, bb->succs)
	if (e != e2)
	  {
	    /* If we made a BB unconditionally exit a loop or removed
	       an entry into an irreducible region, then this transform
	       alters the set of BBs in the loop.  Schedule a fixup.  */
	    if (loop_exit_edge_p (bb->loop_father, e)
		|| (e2->dest->flags & BB_IRREDUCIBLE_LOOP))
	      loops_state_set (LOOPS_NEED_FIXUP);
	    to_remove_edges.safe_push (e2);
	  }
    }

  /* If this is a store into a variable that is being optimized away,
     add a debug bind stmt if possible.  */
  if (MAY_HAVE_DEBUG_BIND_STMTS
      && gimple_assign_single_p (stmt)
      && is_gimple_val (gimple_assign_rhs1 (stmt)))
    {
      tree lhs = gimple_assign_lhs (stmt);
      if ((VAR_P (lhs) || TREE_CODE (lhs) == PARM_DECL)
	  && !DECL_IGNORED_P (lhs)
	  && is_gimple_reg_type (TREE_TYPE (lhs))
	  && !is_global_var (lhs)
	  && !DECL_HAS_VALUE_EXPR_P (lhs))
	{
	  tree rhs = gimple_assign_rhs1 (stmt);
	  gdebug *note
	    = gimple_build_debug_bind (lhs, unshare_expr (rhs), stmt);
	  gsi_insert_after (i, note, GSI_SAME_STMT);
	}
    }

  unlink_stmt_vdef (stmt);
  gsi_remove (i, true);
  release_defs (stmt);
}

/* Helper for maybe_optimize_arith_overflow.  Find in *TP if there are any
   uses of data (SSA_NAME) other than REALPART_EXPR referencing it.  */

static tree
find_non_realpart_uses (tree *tp, int *walk_subtrees, void *data)
{
  if (TYPE_P (*tp) || TREE_CODE (*tp) == REALPART_EXPR)
    *walk_subtrees = 0;
  if (*tp == (tree) data)
    return *tp;
  return NULL_TREE;
}

/* If the IMAGPART_EXPR of the {ADD,SUB,MUL}_OVERFLOW result is never used,
   but REALPART_EXPR is, optimize the {ADD,SUB,MUL}_OVERFLOW internal calls
   into plain unsigned {PLUS,MINUS,MULT}_EXPR, and if needed reset debug
   uses.  */

static void
maybe_optimize_arith_overflow (gimple_stmt_iterator *gsi,
			       enum tree_code subcode)
{
  gimple *stmt = gsi_stmt (*gsi);
  tree lhs = gimple_call_lhs (stmt);

  if (lhs == NULL || TREE_CODE (lhs) != SSA_NAME)
    return;

  imm_use_iterator imm_iter;
  use_operand_p use_p;
  bool has_debug_uses = false;
  bool has_realpart_uses = false;
  bool has_other_uses = false;
  FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs)
    {
      gimple *use_stmt = USE_STMT (use_p);
      if (is_gimple_debug (use_stmt))
	has_debug_uses = true;
      else if (is_gimple_assign (use_stmt)
	       && gimple_assign_rhs_code (use_stmt) == REALPART_EXPR
	       && TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 0) == lhs)
	has_realpart_uses = true;
      else
	{
	  has_other_uses = true;
	  break;
	}
    }

  if (!has_realpart_uses || has_other_uses)
    return;

  tree arg0 = gimple_call_arg (stmt, 0);
  tree arg1 = gimple_call_arg (stmt, 1);
  location_t loc = gimple_location (stmt);
  tree type = TREE_TYPE (TREE_TYPE (lhs));
  tree utype = type;
  if (!TYPE_UNSIGNED (type))
    utype = build_nonstandard_integer_type (TYPE_PRECISION (type), 1);
  tree result = fold_build2_loc (loc, subcode, utype,
				 fold_convert_loc (loc, utype, arg0),
				 fold_convert_loc (loc, utype, arg1));
  result = fold_convert_loc (loc, type, result);

  if (has_debug_uses)
    {
      gimple *use_stmt;
      FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, lhs)
	{
	  if (!gimple_debug_bind_p (use_stmt))
	    continue;
	  tree v = gimple_debug_bind_get_value (use_stmt);
	  if (walk_tree (&v, find_non_realpart_uses, lhs, NULL))
	    {
	      gimple_debug_bind_reset_value (use_stmt);
	      update_stmt (use_stmt);
	    }
	}
    }

  if (TREE_CODE (result) == INTEGER_CST && TREE_OVERFLOW (result))
    result = drop_tree_overflow (result);
  tree overflow = build_zero_cst (type);
  tree ctype = build_complex_type (type);
  if (TREE_CODE (result) == INTEGER_CST)
    result = build_complex (ctype, result, overflow);
  else
    result = build2_loc (gimple_location (stmt), COMPLEX_EXPR,
			 ctype, result, overflow);

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Transforming call: ");
      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
      fprintf (dump_file, "because the overflow result is never used into: ");
      print_generic_stmt (dump_file, result, TDF_SLIM);
      fprintf (dump_file, "\n");
    }

  gimplify_and_update_call_from_tree (gsi, result);
}

/* Returns whether the control parents of BB are preserved.  */

static bool
control_parents_preserved_p (basic_block bb)
{
  /* If we marked the control parents from BB they are preserved.  */
  if (bitmap_bit_p (visited_control_parents, bb->index))
    return true;

  /* But they can also end up being marked from elsewhere.  */
  bitmap_iterator bi;
  unsigned edge_number;
  EXECUTE_IF_SET_IN_BITMAP (cd->get_edges_dependent_on (bb->index),
			    0, edge_number, bi)
    {
      basic_block cd_bb = cd->get_edge_src (edge_number);
      if (cd_bb != bb
	  && !bitmap_bit_p (last_stmt_necessary, cd_bb->index))
	return false;
    }
  /* And cache the result.  */
  bitmap_set_bit (visited_control_parents, bb->index);
  return true;
}

/* Eliminate unnecessary statements. Any instruction not marked as necessary
   contributes nothing to the program, and can be deleted.  */

static bool
eliminate_unnecessary_stmts (bool aggressive)
{
  bool something_changed = false;
  basic_block bb;
  gimple_stmt_iterator gsi, psi;
  gimple *stmt;
  tree call;
  auto_vec<edge> to_remove_edges;

  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "\nEliminating unnecessary statements:\n");

  clear_special_calls ();

  /* Walking basic blocks and statements in reverse order avoids
     releasing SSA names before any other DEFs that refer to them are
     released.  This helps avoid loss of debug information, as we get
     a chance to propagate all RHSs of removed SSAs into debug uses,
     rather than only the latest ones.  E.g., consider:

     x_3 = y_1 + z_2;
     a_5 = x_3 - b_4;
     # DEBUG a => a_5

     If we were to release x_3 before a_5, when we reached a_5 and
     tried to substitute it into the debug stmt, we'd see x_3 there,
     but x_3's DEF, type, etc would have already been disconnected.
     By going backwards, the debug stmt first changes to:

     # DEBUG a => x_3 - b_4

     and then to:

     # DEBUG a => y_1 + z_2 - b_4

     as desired.  */
  gcc_assert (dom_info_available_p (CDI_DOMINATORS));
  auto_vec<basic_block> h;
  h = get_all_dominated_blocks (CDI_DOMINATORS,
				single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));

  while (h.length ())
    {
      bb = h.pop ();

      /* Remove dead statements.  */
      auto_bitmap debug_seen;
      for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi = psi)
	{
	  stmt = gsi_stmt (gsi);

	  psi = gsi;
	  gsi_prev (&psi);

	  stats.total++;

	  /* We can mark a call to free as not necessary if the
	     defining statement of its argument is not necessary
	     (and thus is getting removed).  */
	  if (gimple_plf (stmt, STMT_NECESSARY)
	      && (gimple_call_builtin_p (stmt, BUILT_IN_FREE)
		  || (is_gimple_call (stmt)
		      && gimple_call_from_new_or_delete (as_a <gcall *> (stmt))
		      && gimple_call_operator_delete_p (as_a <gcall *> (stmt)))))
	    {
	      tree ptr = gimple_call_arg (stmt, 0);
	      if (TREE_CODE (ptr) == SSA_NAME)
		{
		  gimple *def_stmt = SSA_NAME_DEF_STMT (ptr);
		  if (!gimple_nop_p (def_stmt)
		      && !gimple_plf (def_stmt, STMT_NECESSARY))
		    gimple_set_plf (stmt, STMT_NECESSARY, false);
		}
	    }

	  /* If GSI is not necessary then remove it.  */
	  if (!gimple_plf (stmt, STMT_NECESSARY))
	    {
	      /* Keep clobbers that we can keep live live.  */
	      if (gimple_clobber_p (stmt))
		{
		  ssa_op_iter iter;
		  use_operand_p use_p;
		  bool dead = false;
		  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
		    {
		      tree name = USE_FROM_PTR (use_p);
		      if (!SSA_NAME_IS_DEFAULT_DEF (name)
			  && !bitmap_bit_p (processed, SSA_NAME_VERSION (name)))
			{
			  dead = true;
			  break;
			}
		    }
		  if (!dead
		      /* When doing CD-DCE we have to ensure all controls
			 of the stmt are still live.  */
		      && (!aggressive || control_parents_preserved_p (bb)))
		    {
		      bitmap_clear (debug_seen);
		      continue;
		    }
		}
	      if (!is_gimple_debug (stmt))
		something_changed = true;
	      remove_dead_stmt (&gsi, bb, to_remove_edges);
	      continue;
	    }
	  else if (is_gimple_call (stmt))
	    {
	      tree name = gimple_call_lhs (stmt);

	      notice_special_calls (as_a <gcall *> (stmt));

	      /* When LHS of var = call (); is dead, simplify it into
		 call (); saving one operand.  */
	      if (name
		  && TREE_CODE (name) == SSA_NAME
		  && !bitmap_bit_p (processed, SSA_NAME_VERSION (name))
		  /* Avoid doing so for allocation calls which we
		     did not mark as necessary, it will confuse the
		     special logic we apply to malloc/free pair removal.  */
		  && (!(call = gimple_call_fndecl (stmt))
		      || ((DECL_BUILT_IN_CLASS (call) != BUILT_IN_NORMAL
			   || (DECL_FUNCTION_CODE (call) != BUILT_IN_ALIGNED_ALLOC
			       && DECL_FUNCTION_CODE (call) != BUILT_IN_MALLOC
			       && DECL_FUNCTION_CODE (call) != BUILT_IN_CALLOC
			       && !ALLOCA_FUNCTION_CODE_P
			       (DECL_FUNCTION_CODE (call))))
			  && !DECL_IS_REPLACEABLE_OPERATOR_NEW_P (call))))
		{
		  something_changed = true;
		  if (dump_file && (dump_flags & TDF_DETAILS))
		    {
		      fprintf (dump_file, "Deleting LHS of call: ");
		      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
		      fprintf (dump_file, "\n");
		    }

		  gimple_call_set_lhs (stmt, NULL_TREE);
		  maybe_clean_or_replace_eh_stmt (stmt, stmt);
		  update_stmt (stmt);
		  release_ssa_name (name);

		  /* GOMP_SIMD_LANE (unless three argument) or ASAN_POISON
		     without lhs is not needed.  */
		  if (gimple_call_internal_p (stmt))
		    switch (gimple_call_internal_fn (stmt))
		      {
		      case IFN_GOMP_SIMD_LANE:
			if (gimple_call_num_args (stmt) >= 3
			    && !integer_nonzerop (gimple_call_arg (stmt, 2)))
			  break;
			/* FALLTHRU */
		      case IFN_ASAN_POISON:
			remove_dead_stmt (&gsi, bb, to_remove_edges);
			break;
		      default:
			break;
		      }
		}
	      else if (gimple_call_internal_p (stmt))
		switch (gimple_call_internal_fn (stmt))
		  {
		  case IFN_ADD_OVERFLOW:
		    maybe_optimize_arith_overflow (&gsi, PLUS_EXPR);
		    break;
		  case IFN_SUB_OVERFLOW:
		    maybe_optimize_arith_overflow (&gsi, MINUS_EXPR);
		    break;
		  case IFN_MUL_OVERFLOW:
		    maybe_optimize_arith_overflow (&gsi, MULT_EXPR);
		    break;
		  default:
		    break;
		  }
	    }
	  else if (gimple_debug_bind_p (stmt))
	    {
	      /* We are only keeping the last debug-bind of a
	         non-DEBUG_EXPR_DECL variable in a series of
		 debug-bind stmts.  */
	      tree var = gimple_debug_bind_get_var (stmt);
	      if (TREE_CODE (var) != DEBUG_EXPR_DECL
		  && !bitmap_set_bit (debug_seen, DECL_UID (var)))
		remove_dead_stmt (&gsi, bb, to_remove_edges);
	      continue;
	    }
	  bitmap_clear (debug_seen);
	}

      /* Remove dead PHI nodes.  */
      something_changed |= remove_dead_phis (bb);
    }


  /* Since we don't track liveness of virtual PHI nodes, it is possible that we
     rendered some PHI nodes unreachable while they are still in use.
     Mark them for renaming.  */
  if (!to_remove_edges.is_empty ())
    {
      basic_block prev_bb;

      /* Remove edges.  We've delayed this to not get bogus debug stmts
         during PHI node removal.  */
      for (unsigned i = 0; i < to_remove_edges.length (); ++i)
	remove_edge (to_remove_edges[i]);
      cfg_altered = true;

      find_unreachable_blocks ();

      /* Delete all unreachable basic blocks in reverse dominator order.  */
      for (bb = EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb;
	   bb != ENTRY_BLOCK_PTR_FOR_FN (cfun); bb = prev_bb)
	{
	  prev_bb = bb->prev_bb;

	  if (!bitmap_bit_p (bb_contains_live_stmts, bb->index)
	      || !(bb->flags & BB_REACHABLE))
	    {
	      for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
		   gsi_next (&gsi))
		if (virtual_operand_p (gimple_phi_result (gsi.phi ())))
		  {
		    bool found = false;
		    imm_use_iterator iter;

		    FOR_EACH_IMM_USE_STMT (stmt, iter,
					   gimple_phi_result (gsi.phi ()))
		      {
			if (!(gimple_bb (stmt)->flags & BB_REACHABLE))
			  continue;
			if (gimple_code (stmt) == GIMPLE_PHI
			    || gimple_plf (stmt, STMT_NECESSARY))
			  {
			    found = true;
			    break;
			  }
		      }
		    if (found)
		      mark_virtual_phi_result_for_renaming (gsi.phi ());
		  }

	      if (!(bb->flags & BB_REACHABLE))
		{
		  /* Speed up the removal of blocks that don't
		     dominate others.  Walking backwards, this should
		     be the common case.  ??? Do we need to recompute
		     dominators because of cfg_altered?  */
		  if (!first_dom_son (CDI_DOMINATORS, bb))
		    delete_basic_block (bb);
		  else
		    {
		      h = get_all_dominated_blocks (CDI_DOMINATORS, bb);

		      while (h.length ())
			{
			  bb = h.pop ();
			  prev_bb = bb->prev_bb;
			  /* Rearrangements to the CFG may have failed
			     to update the dominators tree, so that
			     formerly-dominated blocks are now
			     otherwise reachable.  */
			  if (!!(bb->flags & BB_REACHABLE))
			    continue;
			  delete_basic_block (bb);
			}

		      h.release ();
		    }
		}
	    }
	}
    }

  if (bb_postorder)
    free (bb_postorder);
  bb_postorder = NULL;

  return something_changed;
}


/* Print out removed statement statistics.  */

static void
print_stats (void)
{
  float percg;

  percg = ((float) stats.removed / (float) stats.total) * 100;
  fprintf (dump_file, "Removed %d of %d statements (%d%%)\n",
	   stats.removed, stats.total, (int) percg);

  if (stats.total_phis == 0)
    percg = 0;
  else
    percg = ((float) stats.removed_phis / (float) stats.total_phis) * 100;

  fprintf (dump_file, "Removed %d of %d PHI nodes (%d%%)\n",
	   stats.removed_phis, stats.total_phis, (int) percg);
}

/* Initialization for this pass.  Set up the used data structures.  */

static void
tree_dce_init (bool aggressive)
{
  memset ((void *) &stats, 0, sizeof (stats));

  if (aggressive)
    {
      last_stmt_necessary = sbitmap_alloc (last_basic_block_for_fn (cfun));
      bitmap_clear (last_stmt_necessary);
      bb_contains_live_stmts = sbitmap_alloc (last_basic_block_for_fn (cfun));
      bitmap_clear (bb_contains_live_stmts);
    }

  processed = sbitmap_alloc (num_ssa_names + 1);
  bitmap_clear (processed);

  worklist.create (64);
  cfg_altered = false;
}

/* Cleanup after this pass.  */

static void
tree_dce_done (bool aggressive)
{
  if (aggressive)
    {
      delete cd;
      sbitmap_free (visited_control_parents);
      sbitmap_free (last_stmt_necessary);
      sbitmap_free (bb_contains_live_stmts);
      bb_contains_live_stmts = NULL;
    }

  sbitmap_free (processed);

  worklist.release ();
}

/* Sort PHI argument values for make_forwarders_with_degenerate_phis.  */

static int
sort_phi_args (const void *a_, const void *b_)
{
  auto *a = (const std::pair<edge, hashval_t> *) a_;
  auto *b = (const std::pair<edge, hashval_t> *) b_;
  hashval_t ha = a->second;
  hashval_t hb = b->second;
  if (ha < hb)
    return -1;
  else if (ha > hb)
    return 1;
  else if (a->first->dest_idx < b->first->dest_idx)
    return -1;
  else if (a->first->dest_idx > b->first->dest_idx)
    return 1;
  else
    return 0;
}

/* Look for a non-virtual PHIs and make a forwarder block when all PHIs
   have the same argument on a set of edges.  This is to not consider
   control dependences of individual edges for same values but only for
   the common set.  */

static unsigned
make_forwarders_with_degenerate_phis (function *fn)
{
  unsigned todo = 0;

  basic_block bb;
  FOR_EACH_BB_FN (bb, fn)
    {
      /* Only PHIs with three or more arguments have opportunities.  */
      if (EDGE_COUNT (bb->preds) < 3)
	continue;
      /* Do not touch loop headers or blocks with abnormal predecessors.
	 ???  This is to avoid creating valid loops here, see PR103458.
	 We might want to improve things to either explicitely add those
	 loops or at least consider blocks with no backedges.  */
      if (bb->loop_father->header == bb
	  || bb_has_abnormal_pred (bb))
	continue;

      /* Take one PHI node as template to look for identical
	 arguments.  Build a vector of candidates forming sets
	 of argument edges with equal values.  Note optimality
	 depends on the particular choice of the template PHI
	 since equal arguments are unordered leaving other PHIs
	 with more than one set of equal arguments within this
	 argument range unsorted.  We'd have to break ties by
	 looking at other PHI nodes.  */
      gphi_iterator gsi = gsi_start_nonvirtual_phis (bb);
      if (gsi_end_p (gsi))
	continue;
      gphi *phi = gsi.phi ();
      auto_vec<std::pair<edge, hashval_t>, 8> args;
      bool need_resort = false;
      for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
	{
	  edge e = gimple_phi_arg_edge (phi, i);
	  /* Skip abnormal edges since we cannot redirect them.  */
	  if (e->flags & EDGE_ABNORMAL)
	    continue;
	  /* Skip loop exit edges when we are in loop-closed SSA form
	     since the forwarder we'd create does not have a PHI node.  */
	  if (loops_state_satisfies_p (LOOP_CLOSED_SSA)
	      && loop_exit_edge_p (e->src->loop_father, e))
	    continue;

	  tree arg = gimple_phi_arg_def (phi, i);
	  if (!CONSTANT_CLASS_P (arg) && TREE_CODE (arg) != SSA_NAME)
	    need_resort = true;
	  args.safe_push (std::make_pair (e, iterative_hash_expr (arg, 0)));
	}
      if (args.length () < 2)
	continue;
      args.qsort (sort_phi_args);
      /* The above sorting can be different between -g and -g0, as e.g. decls
	 can have different uids (-g could have bigger gaps in between them).
	 So, only use that to determine which args are equal, then change
	 second from hash value to smallest dest_idx of the edges which have
	 equal argument and sort again.  If all the phi arguments are
	 constants or SSA_NAME, there is no need for the second sort, the hash
	 values are stable in that case.  */
      hashval_t hash = args[0].second;
      args[0].second = args[0].first->dest_idx;
      bool any_equal = false;
      for (unsigned i = 1; i < args.length (); ++i)
	if (hash == args[i].second
	    && operand_equal_p (PHI_ARG_DEF_FROM_EDGE (phi, args[i - 1].first),
				PHI_ARG_DEF_FROM_EDGE (phi, args[i].first)))
	  {
	    args[i].second = args[i - 1].second;
	    any_equal = true;
	  }
	else
	  {
	    hash = args[i].second;
	    args[i].second = args[i].first->dest_idx;
	  }
      if (!any_equal)
	continue;
      if (need_resort)
	args.qsort (sort_phi_args);

      /* From the candidates vector now verify true candidates for
	 forwarders and create them.  */
      gphi *vphi = get_virtual_phi (bb);
      unsigned start = 0;
      while (start < args.length () - 1)
	{
	  unsigned i;
	  for (i = start + 1; i < args.length (); ++i)
	    if (args[start].second != args[i].second)
	      break;
	  /* args[start]..args[i-1] are equal.  */
	  if (start != i - 1)
	    {
	      /* Check all PHI nodes for argument equality.  */
	      bool equal = true;
	      gphi_iterator gsi2 = gsi;
	      gsi_next (&gsi2);
	      for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
		{
		  gphi *phi2 = gsi2.phi ();
		  if (virtual_operand_p (gimple_phi_result (phi2)))
		    continue;
		  tree start_arg
		    = PHI_ARG_DEF_FROM_EDGE (phi2, args[start].first);
		  for (unsigned j = start + 1; j < i; ++j)
		    {
		      if (!operand_equal_p (start_arg,
					    PHI_ARG_DEF_FROM_EDGE
					      (phi2, args[j].first)))
			{
			  /* Another PHI might have a shorter set of
			     equivalent args.  Go for that.  */
			  i = j;
			  if (j == start + 1)
			    equal = false;
			  break;
			}
		    }
		  if (!equal)
		    break;
		}
	      if (equal)
		{
		  /* If we are asked to forward all edges the block
		     has all degenerate PHIs.  Do nothing in that case.  */
		  if (start == 0
		      && i == args.length ()
		      && args.length () == gimple_phi_num_args (phi))
		    break;
		  /* Instead of using make_forwarder_block we are
		     rolling our own variant knowing that the forwarder
		     does not need PHI nodes apart from eventually
		     a virtual one.  */
		  auto_vec<tree, 8> vphi_args;
		  if (vphi)
		    {
		      vphi_args.reserve_exact (i - start);
		      for (unsigned j = start; j < i; ++j)
			vphi_args.quick_push
			  (PHI_ARG_DEF_FROM_EDGE (vphi, args[j].first));
		    }
		  free_dominance_info (fn, CDI_DOMINATORS);
		  basic_block forwarder = split_edge (args[start].first);
		  for (unsigned j = start + 1; j < i; ++j)
		    {
		      edge e = args[j].first;
		      redirect_edge_and_branch_force (e, forwarder);
		      redirect_edge_var_map_clear (e);
		    }
		  if (vphi)
		    {
		      tree def = copy_ssa_name (vphi_args[0]);
		      gphi *vphi_copy = create_phi_node (def, forwarder);
		      for (unsigned j = start; j < i; ++j)
			add_phi_arg (vphi_copy, vphi_args[j - start],
				     args[j].first, UNKNOWN_LOCATION);
		      SET_PHI_ARG_DEF
			(vphi, single_succ_edge (forwarder)->dest_idx, def);
		    }
		  todo |= TODO_cleanup_cfg;
		}
	    }
	  /* Continue searching for more opportunities.  */
	  start = i;
	}
    }
  return todo;
}

/* Main routine to eliminate dead code.

   AGGRESSIVE controls the aggressiveness of the algorithm.
   In conservative mode, we ignore control dependence and simply declare
   all but the most trivially dead branches necessary.  This mode is fast.
   In aggressive mode, control dependences are taken into account, which
   results in more dead code elimination, but at the cost of some time.

   FIXME: Aggressive mode before PRE doesn't work currently because
	  the dominance info is not invalidated after DCE1.  This is
	  not an issue right now because we only run aggressive DCE
	  as the last tree SSA pass, but keep this in mind when you
	  start experimenting with pass ordering.  */

static unsigned int
perform_tree_ssa_dce (bool aggressive)
{
  bool something_changed = 0;
  unsigned todo = 0;

  /* Preheaders are needed for SCEV to work.
     Simple lateches and recorded exits improve chances that loop will
     proved to be finite in testcases such as in loop-15.c and loop-24.c  */
  bool in_loop_pipeline = scev_initialized_p ();
  if (aggressive && ! in_loop_pipeline)
    {
      loop_optimizer_init (LOOPS_NORMAL
			   | LOOPS_HAVE_RECORDED_EXITS);
      scev_initialize ();
    }

  if (aggressive)
    todo |= make_forwarders_with_degenerate_phis (cfun);

  calculate_dominance_info (CDI_DOMINATORS);

  tree_dce_init (aggressive);

  if (aggressive)
    {
      /* Compute control dependence.  */
      calculate_dominance_info (CDI_POST_DOMINATORS);
      cd = new control_dependences ();

      visited_control_parents =
	sbitmap_alloc (last_basic_block_for_fn (cfun));
      bitmap_clear (visited_control_parents);

      mark_dfs_back_edges ();
    }

  find_obviously_necessary_stmts (aggressive);

  if (aggressive && ! in_loop_pipeline)
    {
      scev_finalize ();
      loop_optimizer_finalize ();
    }

  longest_chain = 0;
  total_chain = 0;
  nr_walks = 0;
  chain_ovfl = false;
  visited = BITMAP_ALLOC (NULL);
  propagate_necessity (aggressive);
  BITMAP_FREE (visited);

  something_changed |= eliminate_unnecessary_stmts (aggressive);
  something_changed |= cfg_altered;

  /* We do not update postdominators, so free them unconditionally.  */
  free_dominance_info (CDI_POST_DOMINATORS);

  /* If we removed paths in the CFG, then we need to update
     dominators as well.  I haven't investigated the possibility
     of incrementally updating dominators.  */
  if (cfg_altered)
    free_dominance_info (CDI_DOMINATORS);

  statistics_counter_event (cfun, "Statements deleted", stats.removed);
  statistics_counter_event (cfun, "PHI nodes deleted", stats.removed_phis);

  /* Debugging dumps.  */
  if (dump_file && (dump_flags & (TDF_STATS|TDF_DETAILS)))
    print_stats ();

  tree_dce_done (aggressive);

  if (something_changed)
    {
      free_numbers_of_iterations_estimates (cfun);
      if (in_loop_pipeline)
	scev_reset ();
      todo |= TODO_update_ssa | TODO_cleanup_cfg;
    }
  return todo;
}

/* Pass entry points.  */
static unsigned int
tree_ssa_dce (void)
{
  return perform_tree_ssa_dce (/*aggressive=*/false);
}

static unsigned int
tree_ssa_cd_dce (void)
{
  return perform_tree_ssa_dce (/*aggressive=*/optimize >= 2);
}

namespace {

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

class pass_dce : public gimple_opt_pass
{
public:
  pass_dce (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_dce, ctxt)
  {}

  /* opt_pass methods: */
  opt_pass * clone () final override { return new pass_dce (m_ctxt); }
  bool gate (function *) final override { return flag_tree_dce != 0; }
  unsigned int execute (function *) final override { return tree_ssa_dce (); }

}; // class pass_dce

} // anon namespace

gimple_opt_pass *
make_pass_dce (gcc::context *ctxt)
{
  return new pass_dce (ctxt);
}

namespace {

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

class pass_cd_dce : public gimple_opt_pass
{
public:
  pass_cd_dce (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_cd_dce, ctxt), update_address_taken_p (false)
  {}

  /* opt_pass methods: */
  opt_pass * clone () final override { return new pass_cd_dce (m_ctxt); }
  void set_pass_param (unsigned n, bool param) final override
    {
      gcc_assert (n == 0);
      update_address_taken_p = param;
    }
  bool gate (function *) final override { return flag_tree_dce != 0; }
  unsigned int execute (function *) final override
    {
      return (tree_ssa_cd_dce ()
	      | (update_address_taken_p ? TODO_update_address_taken : 0));
    }

private:
  bool update_address_taken_p;
}; // class pass_cd_dce

} // anon namespace

gimple_opt_pass *
make_pass_cd_dce (gcc::context *ctxt)
{
  return new pass_cd_dce (ctxt);
}


/* A cheap DCE interface.  WORKLIST is a list of possibly dead stmts and
   is consumed by this function.  The function has linear complexity in
   the number of dead stmts with a constant factor like the average SSA
   use operands number.  */

void
simple_dce_from_worklist (bitmap worklist)
{
  while (! bitmap_empty_p (worklist))
    {
      /* Pop item.  */
      unsigned i = bitmap_first_set_bit (worklist);
      bitmap_clear_bit (worklist, i);

      tree def = ssa_name (i);
      /* Removed by somebody else or still in use.  */
      if (! def || ! has_zero_uses (def))
	continue;

      gimple *t = SSA_NAME_DEF_STMT (def);
      if (gimple_has_side_effects (t))
	continue;

      /* Don't remove statements that are needed for non-call
	 eh to work.  */
      if (stmt_unremovable_because_of_non_call_eh_p (cfun, t))
	continue;

      /* Add uses to the worklist.  */
      ssa_op_iter iter;
      use_operand_p use_p;
      FOR_EACH_PHI_OR_STMT_USE (use_p, t, iter, SSA_OP_USE)
	{
	  tree use = USE_FROM_PTR (use_p);
	  if (TREE_CODE (use) == SSA_NAME
	      && ! SSA_NAME_IS_DEFAULT_DEF (use))
	    bitmap_set_bit (worklist, SSA_NAME_VERSION (use));
	}

      /* Remove stmt.  */
      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "Removing dead stmt:");
	  print_gimple_stmt (dump_file, t, 0);
	}
      gimple_stmt_iterator gsi = gsi_for_stmt (t);
      if (gimple_code (t) == GIMPLE_PHI)
	remove_phi_node (&gsi, true);
      else
	{
	  gsi_remove (&gsi, true);
	  release_defs (t);
	}
    }
}
