/* Control flow functions for trees.
   Copyright (C) 2001-2022 Free Software Foundation, Inc.
   Contributed by Diego Novillo <dnovillo@redhat.com>

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 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 "target.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "cfghooks.h"
#include "tree-pass.h"
#include "ssa.h"
#include "cgraph.h"
#include "gimple-pretty-print.h"
#include "diagnostic-core.h"
#include "fold-const.h"
#include "trans-mem.h"
#include "stor-layout.h"
#include "print-tree.h"
#include "cfganal.h"
#include "gimple-iterator.h"
#include "gimple-fold.h"
#include "tree-eh.h"
#include "gimplify-me.h"
#include "gimple-walk.h"
#include "tree-cfg.h"
#include "tree-ssa-loop-manip.h"
#include "tree-ssa-loop-niter.h"
#include "tree-into-ssa.h"
#include "tree-dfa.h"
#include "tree-ssa.h"
#include "except.h"
#include "cfgloop.h"
#include "tree-ssa-propagate.h"
#include "value-prof.h"
#include "tree-inline.h"
#include "tree-ssa-live.h"
#include "tree-ssa-dce.h"
#include "omp-general.h"
#include "omp-expand.h"
#include "tree-cfgcleanup.h"
#include "gimplify.h"
#include "attribs.h"
#include "selftest.h"
#include "opts.h"
#include "asan.h"
#include "profile.h"
#include "sreal.h"

/* This file contains functions for building the Control Flow Graph (CFG)
   for a function tree.  */

/* Local declarations.  */

/* Initial capacity for the basic block array.  */
static const int initial_cfg_capacity = 20;

/* This hash table allows us to efficiently lookup all CASE_LABEL_EXPRs
   which use a particular edge.  The CASE_LABEL_EXPRs are chained together
   via their CASE_CHAIN field, which we clear after we're done with the
   hash table to prevent problems with duplication of GIMPLE_SWITCHes.

   Access to this list of CASE_LABEL_EXPRs allows us to efficiently
   update the case vector in response to edge redirections.

   Right now this table is set up and torn down at key points in the
   compilation process.  It would be nice if we could make the table
   more persistent.  The key is getting notification of changes to
   the CFG (particularly edge removal, creation and redirection).  */

static hash_map<edge, tree> *edge_to_cases;

/* If we record edge_to_cases, this bitmap will hold indexes
   of basic blocks that end in a GIMPLE_SWITCH which we touched
   due to edge manipulations.  */

static bitmap touched_switch_bbs;

/* OpenMP region idxs for blocks during cfg pass.  */
static vec<int> bb_to_omp_idx;

/* CFG statistics.  */
struct cfg_stats_d
{
  long num_merged_labels;
};

static struct cfg_stats_d cfg_stats;

/* Data to pass to replace_block_vars_by_duplicates_1.  */
struct replace_decls_d
{
  hash_map<tree, tree> *vars_map;
  tree to_context;
};

/* Hash table to store last discriminator assigned for each locus.  */
struct locus_discrim_map
{
  int location_line;
  int discriminator;
};

/* Hashtable helpers.  */

struct locus_discrim_hasher : free_ptr_hash <locus_discrim_map>
{
  static inline hashval_t hash (const locus_discrim_map *);
  static inline bool equal (const locus_discrim_map *,
			    const locus_discrim_map *);
};

/* Trivial hash function for a location_t.  ITEM is a pointer to
   a hash table entry that maps a location_t to a discriminator.  */

inline hashval_t
locus_discrim_hasher::hash (const locus_discrim_map *item)
{
  return item->location_line;
}

/* Equality function for the locus-to-discriminator map.  A and B
   point to the two hash table entries to compare.  */

inline bool
locus_discrim_hasher::equal (const locus_discrim_map *a,
			     const locus_discrim_map *b)
{
  return a->location_line == b->location_line;
}

static hash_table<locus_discrim_hasher> *discriminator_per_locus;

/* Basic blocks and flowgraphs.  */
static void make_blocks (gimple_seq);

/* Edges.  */
static void make_edges (void);
static void assign_discriminators (void);
static void make_cond_expr_edges (basic_block);
static void make_gimple_switch_edges (gswitch *, basic_block);
static bool make_goto_expr_edges (basic_block);
static void make_gimple_asm_edges (basic_block);
static edge gimple_redirect_edge_and_branch (edge, basic_block);
static edge gimple_try_redirect_by_replacing_jump (edge, basic_block);

/* Various helpers.  */
static inline bool stmt_starts_bb_p (gimple *, gimple *);
static int gimple_verify_flow_info (void);
static void gimple_make_forwarder_block (edge);
static gimple *first_non_label_stmt (basic_block);
static bool verify_gimple_transaction (gtransaction *);
static bool call_can_make_abnormal_goto (gimple *);

/* Flowgraph optimization and cleanup.  */
static void gimple_merge_blocks (basic_block, basic_block);
static bool gimple_can_merge_blocks_p (basic_block, basic_block);
static void remove_bb (basic_block);
static edge find_taken_edge_computed_goto (basic_block, tree);
static edge find_taken_edge_cond_expr (const gcond *, tree);

void
init_empty_tree_cfg_for_function (struct function *fn)
{
  /* Initialize the basic block array.  */
  init_flow (fn);
  profile_status_for_fn (fn) = PROFILE_ABSENT;
  n_basic_blocks_for_fn (fn) = NUM_FIXED_BLOCKS;
  last_basic_block_for_fn (fn) = NUM_FIXED_BLOCKS;
  vec_safe_grow_cleared (basic_block_info_for_fn (fn),
			 initial_cfg_capacity, true);

  /* Build a mapping of labels to their associated blocks.  */
  vec_safe_grow_cleared (label_to_block_map_for_fn (fn),
			 initial_cfg_capacity, true);

  SET_BASIC_BLOCK_FOR_FN (fn, ENTRY_BLOCK, ENTRY_BLOCK_PTR_FOR_FN (fn));
  SET_BASIC_BLOCK_FOR_FN (fn, EXIT_BLOCK, EXIT_BLOCK_PTR_FOR_FN (fn));

  ENTRY_BLOCK_PTR_FOR_FN (fn)->next_bb
    = EXIT_BLOCK_PTR_FOR_FN (fn);
  EXIT_BLOCK_PTR_FOR_FN (fn)->prev_bb
    = ENTRY_BLOCK_PTR_FOR_FN (fn);
}

void
init_empty_tree_cfg (void)
{
  init_empty_tree_cfg_for_function (cfun);
}

/*---------------------------------------------------------------------------
			      Create basic blocks
---------------------------------------------------------------------------*/

/* Entry point to the CFG builder for trees.  SEQ is the sequence of
   statements to be added to the flowgraph.  */

static void
build_gimple_cfg (gimple_seq seq)
{
  /* Register specific gimple functions.  */
  gimple_register_cfg_hooks ();

  memset ((void *) &cfg_stats, 0, sizeof (cfg_stats));

  init_empty_tree_cfg ();

  make_blocks (seq);

  /* Make sure there is always at least one block, even if it's empty.  */
  if (n_basic_blocks_for_fn (cfun) == NUM_FIXED_BLOCKS)
    create_empty_bb (ENTRY_BLOCK_PTR_FOR_FN (cfun));

  /* Adjust the size of the array.  */
  if (basic_block_info_for_fn (cfun)->length ()
      < (size_t) n_basic_blocks_for_fn (cfun))
    vec_safe_grow_cleared (basic_block_info_for_fn (cfun),
			   n_basic_blocks_for_fn (cfun));

  /* To speed up statement iterator walks, we first purge dead labels.  */
  cleanup_dead_labels ();

  /* Group case nodes to reduce the number of edges.
     We do this after cleaning up dead labels because otherwise we miss
     a lot of obvious case merging opportunities.  */
  group_case_labels ();

  /* Create the edges of the flowgraph.  */
  discriminator_per_locus = new hash_table<locus_discrim_hasher> (13);
  make_edges ();
  assign_discriminators ();
  cleanup_dead_labels ();
  delete discriminator_per_locus;
  discriminator_per_locus = NULL;
}

/* Look for ANNOTATE calls with loop annotation kind in BB; if found, remove
   them and propagate the information to LOOP.  We assume that the annotations
   come immediately before the condition in BB, if any.  */

static void
replace_loop_annotate_in_block (basic_block bb, class loop *loop)
{
  gimple_stmt_iterator gsi = gsi_last_bb (bb);
  gimple *stmt = gsi_stmt (gsi);

  if (!(stmt && gimple_code (stmt) == GIMPLE_COND))
    return;

  for (gsi_prev_nondebug (&gsi); !gsi_end_p (gsi); gsi_prev (&gsi))
    {
      stmt = gsi_stmt (gsi);
      if (gimple_code (stmt) != GIMPLE_CALL)
	break;
      if (!gimple_call_internal_p (stmt)
	  || gimple_call_internal_fn (stmt) != IFN_ANNOTATE)
	break;

      switch ((annot_expr_kind) tree_to_shwi (gimple_call_arg (stmt, 1)))
	{
	case annot_expr_ivdep_kind:
	  loop->safelen = INT_MAX;
	  break;
	case annot_expr_unroll_kind:
	  loop->unroll
	    = (unsigned short) tree_to_shwi (gimple_call_arg (stmt, 2));
	  cfun->has_unroll = true;
	  break;
	case annot_expr_no_vector_kind:
	  loop->dont_vectorize = true;
	  break;
	case annot_expr_vector_kind:
	  loop->force_vectorize = true;
	  cfun->has_force_vectorize_loops = true;
	  break;
	case annot_expr_parallel_kind:
	  loop->can_be_parallel = true;
	  loop->safelen = INT_MAX;
	  break;
	default:
	  gcc_unreachable ();
	}

      stmt = gimple_build_assign (gimple_call_lhs (stmt),
				  gimple_call_arg (stmt, 0));
      gsi_replace (&gsi, stmt, true);
    }
}

/* Look for ANNOTATE calls with loop annotation kind; if found, remove
   them and propagate the information to the loop.  We assume that the
   annotations come immediately before the condition of the loop.  */

static void
replace_loop_annotate (void)
{
  basic_block bb;
  gimple_stmt_iterator gsi;
  gimple *stmt;

  for (auto loop : loops_list (cfun, 0))
    {
      /* First look into the header.  */
      replace_loop_annotate_in_block (loop->header, loop);

      /* Then look into the latch, if any.  */
      if (loop->latch)
	replace_loop_annotate_in_block (loop->latch, loop);

      /* Push the global flag_finite_loops state down to individual loops.  */
      loop->finite_p = flag_finite_loops;
    }

  /* Remove IFN_ANNOTATE.  Safeguard for the case loop->latch == NULL.  */
  FOR_EACH_BB_FN (bb, cfun)
    {
      for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
	{
	  stmt = gsi_stmt (gsi);
	  if (gimple_code (stmt) != GIMPLE_CALL)
	    continue;
	  if (!gimple_call_internal_p (stmt)
	      || gimple_call_internal_fn (stmt) != IFN_ANNOTATE)
	    continue;

	  switch ((annot_expr_kind) tree_to_shwi (gimple_call_arg (stmt, 1)))
	    {
	    case annot_expr_ivdep_kind:
	    case annot_expr_unroll_kind:
	    case annot_expr_no_vector_kind:
	    case annot_expr_vector_kind:
	    case annot_expr_parallel_kind:
	      break;
	    default:
	      gcc_unreachable ();
	    }

	  warning_at (gimple_location (stmt), 0, "ignoring loop annotation");
	  stmt = gimple_build_assign (gimple_call_lhs (stmt),
				      gimple_call_arg (stmt, 0));
	  gsi_replace (&gsi, stmt, true);
	}
    }
}

static unsigned int
execute_build_cfg (void)
{
  gimple_seq body = gimple_body (current_function_decl);

  build_gimple_cfg (body);
  gimple_set_body (current_function_decl, NULL);
  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Scope blocks:\n");
      dump_scope_blocks (dump_file, dump_flags);
    }
  cleanup_tree_cfg ();

  bb_to_omp_idx.release ();

  loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
  replace_loop_annotate ();
  return 0;
}

namespace {

const pass_data pass_data_build_cfg =
{
  GIMPLE_PASS, /* type */
  "cfg", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_TREE_CFG, /* tv_id */
  PROP_gimple_leh, /* properties_required */
  ( PROP_cfg | PROP_loops ), /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_build_cfg : public gimple_opt_pass
{
public:
  pass_build_cfg (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_build_cfg, ctxt)
  {}

  /* opt_pass methods: */
  unsigned int execute (function *) final override
  {
    return execute_build_cfg ();
  }

}; // class pass_build_cfg

} // anon namespace

gimple_opt_pass *
make_pass_build_cfg (gcc::context *ctxt)
{
  return new pass_build_cfg (ctxt);
}


/* Return true if T is a computed goto.  */

bool
computed_goto_p (gimple *t)
{
  return (gimple_code (t) == GIMPLE_GOTO
	  && TREE_CODE (gimple_goto_dest (t)) != LABEL_DECL);
}

/* Returns true if the sequence of statements STMTS only contains
   a call to __builtin_unreachable ().  */

bool
gimple_seq_unreachable_p (gimple_seq stmts)
{
  if (stmts == NULL
      /* Return false if -fsanitize=unreachable, we don't want to
	 optimize away those calls, but rather turn them into
	 __ubsan_handle_builtin_unreachable () or __builtin_trap ()
	 later.  */
      || sanitize_flags_p (SANITIZE_UNREACHABLE))
    return false;

  gimple_stmt_iterator gsi = gsi_last (stmts);

  if (!gimple_call_builtin_p (gsi_stmt (gsi), BUILT_IN_UNREACHABLE))
    return false;

  for (gsi_prev (&gsi); !gsi_end_p (gsi); gsi_prev (&gsi))
    {
      gimple *stmt = gsi_stmt (gsi);
      if (gimple_code (stmt) != GIMPLE_LABEL
	  && !is_gimple_debug (stmt)
	  && !gimple_clobber_p (stmt))
      return false;
    }
  return true;
}

/* Returns true for edge E where e->src ends with a GIMPLE_COND and
   the other edge points to a bb with just __builtin_unreachable ().
   I.e. return true for C->M edge in:
   <bb C>:
   ...
   if (something)
     goto <bb N>;
   else
     goto <bb M>;
   <bb N>:
   __builtin_unreachable ();
   <bb M>:  */

bool
assert_unreachable_fallthru_edge_p (edge e)
{
  basic_block pred_bb = e->src;
  gimple *last = last_stmt (pred_bb);
  if (last && gimple_code (last) == GIMPLE_COND)
    {
      basic_block other_bb = EDGE_SUCC (pred_bb, 0)->dest;
      if (other_bb == e->dest)
	other_bb = EDGE_SUCC (pred_bb, 1)->dest;
      if (EDGE_COUNT (other_bb->succs) == 0)
	return gimple_seq_unreachable_p (bb_seq (other_bb));
    }
  return false;
}


/* Initialize GF_CALL_CTRL_ALTERING flag, which indicates the call
   could alter control flow except via eh. We initialize the flag at
   CFG build time and only ever clear it later.  */

static void
gimple_call_initialize_ctrl_altering (gimple *stmt)
{
  int flags = gimple_call_flags (stmt);

  /* A call alters control flow if it can make an abnormal goto.  */
  if (call_can_make_abnormal_goto (stmt)
      /* A call also alters control flow if it does not return.  */
      || flags & ECF_NORETURN
      /* TM ending statements have backedges out of the transaction.
	 Return true so we split the basic block containing them.
	 Note that the TM_BUILTIN test is merely an optimization.  */
      || ((flags & ECF_TM_BUILTIN)
	  && is_tm_ending_fndecl (gimple_call_fndecl (stmt)))
      /* BUILT_IN_RETURN call is same as return statement.  */
      || gimple_call_builtin_p (stmt, BUILT_IN_RETURN)
      /* IFN_UNIQUE should be the last insn, to make checking for it
	 as cheap as possible.  */
      || (gimple_call_internal_p (stmt)
	  && gimple_call_internal_unique_p (stmt)))
    gimple_call_set_ctrl_altering (stmt, true);
  else
    gimple_call_set_ctrl_altering (stmt, false);
}


/* Insert SEQ after BB and build a flowgraph.  */

static basic_block
make_blocks_1 (gimple_seq seq, basic_block bb)
{
  gimple_stmt_iterator i = gsi_start (seq);
  gimple *stmt = NULL;
  gimple *prev_stmt = NULL;
  bool start_new_block = true;
  bool first_stmt_of_seq = true;

  while (!gsi_end_p (i))
    {
      /* PREV_STMT should only be set to a debug stmt if the debug
	 stmt is before nondebug stmts.  Once stmt reaches a nondebug
	 nonlabel, prev_stmt will be set to it, so that
	 stmt_starts_bb_p will know to start a new block if a label is
	 found.  However, if stmt was a label after debug stmts only,
	 keep the label in prev_stmt even if we find further debug
	 stmts, for there may be other labels after them, and they
	 should land in the same block.  */
      if (!prev_stmt || !stmt || !is_gimple_debug (stmt))
	prev_stmt = stmt;
      stmt = gsi_stmt (i);

      if (stmt && is_gimple_call (stmt))
	gimple_call_initialize_ctrl_altering (stmt);

      /* If the statement starts a new basic block or if we have determined
	 in a previous pass that we need to create a new block for STMT, do
	 so now.  */
      if (start_new_block || stmt_starts_bb_p (stmt, prev_stmt))
	{
	  if (!first_stmt_of_seq)
	    gsi_split_seq_before (&i, &seq);
	  bb = create_basic_block (seq, bb);
	  start_new_block = false;
	  prev_stmt = NULL;
	}

      /* Now add STMT to BB and create the subgraphs for special statement
	 codes.  */
      gimple_set_bb (stmt, bb);

      /* If STMT is a basic block terminator, set START_NEW_BLOCK for the
	 next iteration.  */
      if (stmt_ends_bb_p (stmt))
	{
	  /* If the stmt can make abnormal goto use a new temporary
	     for the assignment to the LHS.  This makes sure the old value
	     of the LHS is available on the abnormal edge.  Otherwise
	     we will end up with overlapping life-ranges for abnormal
	     SSA names.  */
	  if (gimple_has_lhs (stmt)
	      && stmt_can_make_abnormal_goto (stmt)
	      && is_gimple_reg_type (TREE_TYPE (gimple_get_lhs (stmt))))
	    {
	      tree lhs = gimple_get_lhs (stmt);
	      tree tmp = create_tmp_var (TREE_TYPE (lhs));
	      gimple *s = gimple_build_assign (lhs, tmp);
	      gimple_set_location (s, gimple_location (stmt));
	      gimple_set_block (s, gimple_block (stmt));
	      gimple_set_lhs (stmt, tmp);
	      gsi_insert_after (&i, s, GSI_SAME_STMT);
	    }
	  start_new_block = true;
	}

      gsi_next (&i);
      first_stmt_of_seq = false;
    }
  return bb;
}

/* Build a flowgraph for the sequence of stmts SEQ.  */

static void
make_blocks (gimple_seq seq)
{
  /* Look for debug markers right before labels, and move the debug
     stmts after the labels.  Accepting labels among debug markers
     adds no value, just complexity; if we wanted to annotate labels
     with view numbers (so sequencing among markers would matter) or
     somesuch, we're probably better off still moving the labels, but
     adding other debug annotations in their original positions or
     emitting nonbind or bind markers associated with the labels in
     the original position of the labels.

     Moving labels would probably be simpler, but we can't do that:
     moving labels assigns label ids to them, and doing so because of
     debug markers makes for -fcompare-debug and possibly even codegen
     differences.  So, we have to move the debug stmts instead.  To
     that end, we scan SEQ backwards, marking the position of the
     latest (earliest we find) label, and moving debug stmts that are
     not separated from it by nondebug nonlabel stmts after the
     label.  */
  if (MAY_HAVE_DEBUG_MARKER_STMTS)
    {
      gimple_stmt_iterator label = gsi_none ();

      for (gimple_stmt_iterator i = gsi_last (seq); !gsi_end_p (i); gsi_prev (&i))
	{
	  gimple *stmt = gsi_stmt (i);

	  /* If this is the first label we encounter (latest in SEQ)
	     before nondebug stmts, record its position.  */
	  if (is_a <glabel *> (stmt))
	    {
	      if (gsi_end_p (label))
		label = i;
	      continue;
	    }

	  /* Without a recorded label position to move debug stmts to,
	     there's nothing to do.  */
	  if (gsi_end_p (label))
	    continue;

	  /* Move the debug stmt at I after LABEL.  */
	  if (is_gimple_debug (stmt))
	    {
	      gcc_assert (gimple_debug_nonbind_marker_p (stmt));
	      /* As STMT is removed, I advances to the stmt after
		 STMT, so the gsi_prev in the for "increment"
		 expression gets us to the stmt we're to visit after
		 STMT.  LABEL, however, would advance to the moved
		 stmt if we passed it to gsi_move_after, so pass it a
		 copy instead, so as to keep LABEL pointing to the
		 LABEL.  */
	      gimple_stmt_iterator copy = label;
	      gsi_move_after (&i, &copy);
	      continue;
	    }

	  /* There aren't any (more?) debug stmts before label, so
	     there isn't anything else to move after it.  */
	  label = gsi_none ();
	}
    }

  make_blocks_1 (seq, ENTRY_BLOCK_PTR_FOR_FN (cfun));
}

/* Create and return a new empty basic block after bb AFTER.  */

static basic_block
create_bb (void *h, void *e, basic_block after)
{
  basic_block bb;

  gcc_assert (!e);

  /* Create and initialize a new basic block.  Since alloc_block uses
     GC allocation that clears memory to allocate a basic block, we do
     not have to clear the newly allocated basic block here.  */
  bb = alloc_block ();

  bb->index = last_basic_block_for_fn (cfun);
  bb->flags = BB_NEW;
  set_bb_seq (bb, h ? (gimple_seq) h : NULL);

  /* Add the new block to the linked list of blocks.  */
  link_block (bb, after);

  /* Grow the basic block array if needed.  */
  if ((size_t) last_basic_block_for_fn (cfun)
      == basic_block_info_for_fn (cfun)->length ())
    vec_safe_grow_cleared (basic_block_info_for_fn (cfun),
			   last_basic_block_for_fn (cfun) + 1);

  /* Add the newly created block to the array.  */
  SET_BASIC_BLOCK_FOR_FN (cfun, last_basic_block_for_fn (cfun), bb);

  n_basic_blocks_for_fn (cfun)++;
  last_basic_block_for_fn (cfun)++;

  return bb;
}


/*---------------------------------------------------------------------------
				 Edge creation
---------------------------------------------------------------------------*/

/* If basic block BB has an abnormal edge to a basic block
   containing IFN_ABNORMAL_DISPATCHER internal call, return
   that the dispatcher's basic block, otherwise return NULL.  */

basic_block
get_abnormal_succ_dispatcher (basic_block bb)
{
  edge e;
  edge_iterator ei;

  FOR_EACH_EDGE (e, ei, bb->succs)
    if ((e->flags & (EDGE_ABNORMAL | EDGE_EH)) == EDGE_ABNORMAL)
      {
	gimple_stmt_iterator gsi
	  = gsi_start_nondebug_after_labels_bb (e->dest);
	gimple *g = gsi_stmt (gsi);
	if (g && gimple_call_internal_p (g, IFN_ABNORMAL_DISPATCHER))
	  return e->dest;
      }
  return NULL;
}

/* Helper function for make_edges.  Create a basic block with
   with ABNORMAL_DISPATCHER internal call in it if needed, and
   create abnormal edges from BBS to it and from it to FOR_BB
   if COMPUTED_GOTO is false, otherwise factor the computed gotos.  */

static void
handle_abnormal_edges (basic_block *dispatcher_bbs, basic_block for_bb,
		       auto_vec<basic_block> *bbs, bool computed_goto)
{
  basic_block *dispatcher = dispatcher_bbs + (computed_goto ? 1 : 0);
  unsigned int idx = 0;
  basic_block bb;
  bool inner = false;

  if (!bb_to_omp_idx.is_empty ())
    {
      dispatcher = dispatcher_bbs + 2 * bb_to_omp_idx[for_bb->index];
      if (bb_to_omp_idx[for_bb->index] != 0)
	inner = true;
    }

  /* If the dispatcher has been created already, then there are basic
     blocks with abnormal edges to it, so just make a new edge to
     for_bb.  */
  if (*dispatcher == NULL)
    {
      /* Check if there are any basic blocks that need to have
	 abnormal edges to this dispatcher.  If there are none, return
	 early.  */
      if (bb_to_omp_idx.is_empty ())
	{
	  if (bbs->is_empty ())
	    return;
	}
      else
	{
	  FOR_EACH_VEC_ELT (*bbs, idx, bb)
	    if (bb_to_omp_idx[bb->index] == bb_to_omp_idx[for_bb->index])
	      break;
	  if (bb == NULL)
	    return;
	}

      /* Create the dispatcher bb.  */
      *dispatcher = create_basic_block (NULL, for_bb);
      if (computed_goto)
	{
	  /* Factor computed gotos into a common computed goto site.  Also
	     record the location of that site so that we can un-factor the
	     gotos after we have converted back to normal form.  */
	  gimple_stmt_iterator gsi = gsi_start_bb (*dispatcher);

	  /* Create the destination of the factored goto.  Each original
	     computed goto will put its desired destination into this
	     variable and jump to the label we create immediately below.  */
	  tree var = create_tmp_var (ptr_type_node, "gotovar");

	  /* Build a label for the new block which will contain the
	     factored computed goto.  */
	  tree factored_label_decl
	    = create_artificial_label (UNKNOWN_LOCATION);
	  gimple *factored_computed_goto_label
	    = gimple_build_label (factored_label_decl);
	  gsi_insert_after (&gsi, factored_computed_goto_label, GSI_NEW_STMT);

	  /* Build our new computed goto.  */
	  gimple *factored_computed_goto = gimple_build_goto (var);
	  gsi_insert_after (&gsi, factored_computed_goto, GSI_NEW_STMT);

	  FOR_EACH_VEC_ELT (*bbs, idx, bb)
	    {
	      if (!bb_to_omp_idx.is_empty ()
		  && bb_to_omp_idx[bb->index] != bb_to_omp_idx[for_bb->index])
		continue;

	      gsi = gsi_last_bb (bb);
	      gimple *last = gsi_stmt (gsi);

	      gcc_assert (computed_goto_p (last));

	      /* Copy the original computed goto's destination into VAR.  */
	      gimple *assignment
		= gimple_build_assign (var, gimple_goto_dest (last));
	      gsi_insert_before (&gsi, assignment, GSI_SAME_STMT);

	      edge e = make_edge (bb, *dispatcher, EDGE_FALLTHRU);
	      e->goto_locus = gimple_location (last);
	      gsi_remove (&gsi, true);
	    }
	}
      else
	{
	  tree arg = inner ? boolean_true_node : boolean_false_node;
	  gcall *g = gimple_build_call_internal (IFN_ABNORMAL_DISPATCHER,
						 1, arg);
	  gimple_call_set_ctrl_altering (g, true);
	  gimple_stmt_iterator gsi = gsi_after_labels (*dispatcher);
	  gsi_insert_after (&gsi, g, GSI_NEW_STMT);

	  /* Create predecessor edges of the dispatcher.  */
	  FOR_EACH_VEC_ELT (*bbs, idx, bb)
	    {
	      if (!bb_to_omp_idx.is_empty ()
		  && bb_to_omp_idx[bb->index] != bb_to_omp_idx[for_bb->index])
		continue;
	      make_edge (bb, *dispatcher, EDGE_ABNORMAL);
	    }
	}
    }

  make_edge (*dispatcher, for_bb, EDGE_ABNORMAL);
}

/* Creates outgoing edges for BB.  Returns 1 when it ends with an
   computed goto, returns 2 when it ends with a statement that
   might return to this function via an nonlocal goto, otherwise
   return 0.  Updates *PCUR_REGION with the OMP region this BB is in.  */

static int
make_edges_bb (basic_block bb, struct omp_region **pcur_region, int *pomp_index)
{
  gimple *last = last_stmt (bb);
  bool fallthru = false;
  int ret = 0;

  if (!last)
    return ret;

  switch (gimple_code (last))
    {
    case GIMPLE_GOTO:
      if (make_goto_expr_edges (bb))
	ret = 1;
      fallthru = false;
      break;
    case GIMPLE_RETURN:
      {
	edge e = make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
	e->goto_locus = gimple_location (last);
	fallthru = false;
      }
      break;
    case GIMPLE_COND:
      make_cond_expr_edges (bb);
      fallthru = false;
      break;
    case GIMPLE_SWITCH:
      make_gimple_switch_edges (as_a <gswitch *> (last), bb);
      fallthru = false;
      break;
    case GIMPLE_RESX:
      make_eh_edges (last);
      fallthru = false;
      break;
    case GIMPLE_EH_DISPATCH:
      fallthru = make_eh_dispatch_edges (as_a <geh_dispatch *> (last));
      break;

    case GIMPLE_CALL:
      /* If this function receives a nonlocal goto, then we need to
	 make edges from this call site to all the nonlocal goto
	 handlers.  */
      if (stmt_can_make_abnormal_goto (last))
	ret = 2;

      /* If this statement has reachable exception handlers, then
	 create abnormal edges to them.  */
      make_eh_edges (last);

      /* BUILTIN_RETURN is really a return statement.  */
      if (gimple_call_builtin_p (last, BUILT_IN_RETURN))
	{
	  make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
	  fallthru = false;
	}
      /* Some calls are known not to return.  */
      else
	fallthru = !gimple_call_noreturn_p (last);
      break;

    case GIMPLE_ASSIGN:
      /* A GIMPLE_ASSIGN may throw internally and thus be considered
	 control-altering.  */
      if (is_ctrl_altering_stmt (last))
	make_eh_edges (last);
      fallthru = true;
      break;

    case GIMPLE_ASM:
      make_gimple_asm_edges (bb);
      fallthru = true;
      break;

    CASE_GIMPLE_OMP:
      fallthru = omp_make_gimple_edges (bb, pcur_region, pomp_index);
      break;

    case GIMPLE_TRANSACTION:
      {
        gtransaction *txn = as_a <gtransaction *> (last);
	tree label1 = gimple_transaction_label_norm (txn);
	tree label2 = gimple_transaction_label_uninst (txn);

	if (label1)
	  make_edge (bb, label_to_block (cfun, label1), EDGE_FALLTHRU);
	if (label2)
	  make_edge (bb, label_to_block (cfun, label2),
		     EDGE_TM_UNINSTRUMENTED | (label1 ? 0 : EDGE_FALLTHRU));

	tree label3 = gimple_transaction_label_over (txn);
	if (gimple_transaction_subcode (txn)
	    & (GTMA_HAVE_ABORT | GTMA_IS_OUTER))
	  make_edge (bb, label_to_block (cfun, label3), EDGE_TM_ABORT);

	fallthru = false;
      }
      break;

    default:
      gcc_assert (!stmt_ends_bb_p (last));
      fallthru = true;
      break;
    }

  if (fallthru)
    make_edge (bb, bb->next_bb, EDGE_FALLTHRU);

  return ret;
}

/* Join all the blocks in the flowgraph.  */

static void
make_edges (void)
{
  basic_block bb;
  struct omp_region *cur_region = NULL;
  auto_vec<basic_block> ab_edge_goto;
  auto_vec<basic_block> ab_edge_call;
  int cur_omp_region_idx = 0;

  /* Create an edge from entry to the first block with executable
     statements in it.  */
  make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun),
	     BASIC_BLOCK_FOR_FN (cfun, NUM_FIXED_BLOCKS),
	     EDGE_FALLTHRU);

  /* Traverse the basic block array placing edges.  */
  FOR_EACH_BB_FN (bb, cfun)
    {
      int mer;

      if (!bb_to_omp_idx.is_empty ())
	bb_to_omp_idx[bb->index] = cur_omp_region_idx;

      mer = make_edges_bb (bb, &cur_region, &cur_omp_region_idx);
      if (mer == 1)
	ab_edge_goto.safe_push (bb);
      else if (mer == 2)
	ab_edge_call.safe_push (bb);

      if (cur_region && bb_to_omp_idx.is_empty ())
	bb_to_omp_idx.safe_grow_cleared (n_basic_blocks_for_fn (cfun), true);
    }

  /* Computed gotos are hell to deal with, especially if there are
     lots of them with a large number of destinations.  So we factor
     them to a common computed goto location before we build the
     edge list.  After we convert back to normal form, we will un-factor
     the computed gotos since factoring introduces an unwanted jump.
     For non-local gotos and abnormal edges from calls to calls that return
     twice or forced labels, factor the abnormal edges too, by having all
     abnormal edges from the calls go to a common artificial basic block
     with ABNORMAL_DISPATCHER internal call and abnormal edges from that
     basic block to all forced labels and calls returning twice.
     We do this per-OpenMP structured block, because those regions
     are guaranteed to be single entry single exit by the standard,
     so it is not allowed to enter or exit such regions abnormally this way,
     thus all computed gotos, non-local gotos and setjmp/longjmp calls
     must not transfer control across SESE region boundaries.  */
  if (!ab_edge_goto.is_empty () || !ab_edge_call.is_empty ())
    {
      gimple_stmt_iterator gsi;
      basic_block dispatcher_bb_array[2] = { NULL, NULL };
      basic_block *dispatcher_bbs = dispatcher_bb_array;
      int count = n_basic_blocks_for_fn (cfun);

      if (!bb_to_omp_idx.is_empty ())
	dispatcher_bbs = XCNEWVEC (basic_block, 2 * count);

      FOR_EACH_BB_FN (bb, cfun)
	{
	  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
	    {
	      glabel *label_stmt = dyn_cast <glabel *> (gsi_stmt (gsi));
	      tree target;

	      if (!label_stmt)
		break;

	      target = gimple_label_label (label_stmt);

	      /* Make an edge to every label block that has been marked as a
		 potential target for a computed goto or a non-local goto.  */
	      if (FORCED_LABEL (target))
		handle_abnormal_edges (dispatcher_bbs, bb, &ab_edge_goto,
				       true);
	      if (DECL_NONLOCAL (target))
		{
		  handle_abnormal_edges (dispatcher_bbs, bb, &ab_edge_call,
					 false);
		  break;
		}
	    }

	  if (!gsi_end_p (gsi) && is_gimple_debug (gsi_stmt (gsi)))
	    gsi_next_nondebug (&gsi);
	  if (!gsi_end_p (gsi))
	    {
	      /* Make an edge to every setjmp-like call.  */
	      gimple *call_stmt = gsi_stmt (gsi);
	      if (is_gimple_call (call_stmt)
		  && ((gimple_call_flags (call_stmt) & ECF_RETURNS_TWICE)
		      || gimple_call_builtin_p (call_stmt,
						BUILT_IN_SETJMP_RECEIVER)))
		handle_abnormal_edges (dispatcher_bbs, bb, &ab_edge_call,
				       false);
	    }
	}

      if (!bb_to_omp_idx.is_empty ())
	XDELETE (dispatcher_bbs);
    }

  omp_free_regions ();
}

/* Add SEQ after GSI.  Start new bb after GSI, and created further bbs as
   needed.  Returns true if new bbs were created.
   Note: This is transitional code, and should not be used for new code.  We
   should be able to get rid of this by rewriting all target va-arg
   gimplification hooks to use an interface gimple_build_cond_value as described
   in https://gcc.gnu.org/ml/gcc-patches/2015-02/msg01194.html.  */

bool
gimple_find_sub_bbs (gimple_seq seq, gimple_stmt_iterator *gsi)
{
  gimple *stmt = gsi_stmt (*gsi);
  basic_block bb = gimple_bb (stmt);
  basic_block lastbb, afterbb;
  int old_num_bbs = n_basic_blocks_for_fn (cfun);
  edge e;
  lastbb = make_blocks_1 (seq, bb);
  if (old_num_bbs == n_basic_blocks_for_fn (cfun))
    return false;
  e = split_block (bb, stmt);
  /* Move e->dest to come after the new basic blocks.  */
  afterbb = e->dest;
  unlink_block (afterbb);
  link_block (afterbb, lastbb);
  redirect_edge_succ (e, bb->next_bb);
  bb = bb->next_bb;
  while (bb != afterbb)
    {
      struct omp_region *cur_region = NULL;
      profile_count cnt = profile_count::zero ();
      bool all = true;

      int cur_omp_region_idx = 0;
      int mer = make_edges_bb (bb, &cur_region, &cur_omp_region_idx);
      gcc_assert (!mer && !cur_region);
      add_bb_to_loop (bb, afterbb->loop_father);

      edge e;
      edge_iterator ei;
      FOR_EACH_EDGE (e, ei, bb->preds)
	{
	  if (e->count ().initialized_p ())
	    cnt += e->count ();
	  else
	    all = false;
	}
      tree_guess_outgoing_edge_probabilities (bb);
      if (all || profile_status_for_fn (cfun) == PROFILE_READ)
        bb->count = cnt;

      bb = bb->next_bb;
    }
  return true;
}

/* Find the next available discriminator value for LOCUS.  The
   discriminator distinguishes among several basic blocks that
   share a common locus, allowing for more accurate sample-based
   profiling.  */

static int
next_discriminator_for_locus (int line)
{
  struct locus_discrim_map item;
  struct locus_discrim_map **slot;

  item.location_line = line;
  item.discriminator = 0;
  slot = discriminator_per_locus->find_slot_with_hash (&item, line, INSERT);
  gcc_assert (slot);
  if (*slot == HTAB_EMPTY_ENTRY)
    {
      *slot = XNEW (struct locus_discrim_map);
      gcc_assert (*slot);
      (*slot)->location_line = line;
      (*slot)->discriminator = 0;
    }
  (*slot)->discriminator++;
  return (*slot)->discriminator;
}

/* Return TRUE if LOCUS1 and LOCUS2 refer to the same source line.  */

static bool
same_line_p (location_t locus1, expanded_location *from, location_t locus2)
{
  expanded_location to;

  if (locus1 == locus2)
    return true;

  to = expand_location (locus2);

  if (from->line != to.line)
    return false;
  if (from->file == to.file)
    return true;
  return (from->file != NULL
          && to.file != NULL
          && filename_cmp (from->file, to.file) == 0);
}

/* Assign a unique discriminator value to all statements in block bb that
   have the same line number as locus. */

static void
assign_discriminator (location_t locus, basic_block bb)
{
  gimple_stmt_iterator gsi;
  int discriminator;

  if (locus == UNKNOWN_LOCATION)
    return;

  expanded_location locus_e = expand_location (locus);

  discriminator = next_discriminator_for_locus (locus_e.line);

  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    {
      gimple *stmt = gsi_stmt (gsi);
      location_t stmt_locus = gimple_location (stmt);
      if (same_line_p (locus, &locus_e, stmt_locus))
	gimple_set_location (stmt,
	    location_with_discriminator (stmt_locus, discriminator));
    }
}

/* Assign discriminators to statement locations.  */

static void
assign_discriminators (void)
{
  basic_block bb;

  FOR_EACH_BB_FN (bb, cfun)
    {
      edge e;
      edge_iterator ei;
      gimple_stmt_iterator gsi;
      location_t curr_locus = UNKNOWN_LOCATION;
      expanded_location curr_locus_e = {};
      int curr_discr = 0;

      /* Traverse the basic block, if two function calls within a basic block
	are mapped to the same line, assign a new discriminator because a call
	stmt could be a split point of a basic block.  */
      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
	{
	  gimple *stmt = gsi_stmt (gsi);

	  if (curr_locus == UNKNOWN_LOCATION)
	    {
	      curr_locus = gimple_location (stmt);
	      curr_locus_e = expand_location (curr_locus);
	    }
	  else if (!same_line_p (curr_locus, &curr_locus_e, gimple_location (stmt)))
	    {
	      curr_locus = gimple_location (stmt);
	      curr_locus_e = expand_location (curr_locus);
	      curr_discr = 0;
	    }
	  else if (curr_discr != 0)
	    {
	      location_t loc = gimple_location (stmt);
	      location_t dloc = location_with_discriminator (loc, curr_discr);
	      gimple_set_location (stmt, dloc);
	    }
	  /* Allocate a new discriminator for CALL stmt.  */
	  if (gimple_code (stmt) == GIMPLE_CALL)
	    curr_discr = next_discriminator_for_locus (curr_locus);
	}

      gimple *last = last_stmt (bb);
      location_t locus = last ? gimple_location (last) : UNKNOWN_LOCATION;
      if (locus == UNKNOWN_LOCATION)
	continue;

      expanded_location locus_e = expand_location (locus);

      FOR_EACH_EDGE (e, ei, bb->succs)
	{
	  gimple *first = first_non_label_stmt (e->dest);
	  gimple *last = last_stmt (e->dest);

	  gimple *stmt_on_same_line = NULL;
	  if (first && same_line_p (locus, &locus_e,
				     gimple_location (first)))
	    stmt_on_same_line = first;
	  else if (last && same_line_p (locus, &locus_e,
					gimple_location (last)))
	    stmt_on_same_line = last;

	  if (stmt_on_same_line)
	    {
	      if (has_discriminator (gimple_location (stmt_on_same_line))
		  && !has_discriminator (locus))
		assign_discriminator (locus, bb);
	      else
		assign_discriminator (locus, e->dest);
	    }
	}
    }
}

/* Create the edges for a GIMPLE_COND starting at block BB.  */

static void
make_cond_expr_edges (basic_block bb)
{
  gcond *entry = as_a <gcond *> (last_stmt (bb));
  gimple *then_stmt, *else_stmt;
  basic_block then_bb, else_bb;
  tree then_label, else_label;
  edge e;

  gcc_assert (entry);
  gcc_assert (gimple_code (entry) == GIMPLE_COND);

  /* Entry basic blocks for each component.  */
  then_label = gimple_cond_true_label (entry);
  else_label = gimple_cond_false_label (entry);
  then_bb = label_to_block (cfun, then_label);
  else_bb = label_to_block (cfun, else_label);
  then_stmt = first_stmt (then_bb);
  else_stmt = first_stmt (else_bb);

  e = make_edge (bb, then_bb, EDGE_TRUE_VALUE);
  e->goto_locus = gimple_location (then_stmt);
  e = make_edge (bb, else_bb, EDGE_FALSE_VALUE);
  if (e)
    e->goto_locus = gimple_location (else_stmt);

  /* We do not need the labels anymore.  */
  gimple_cond_set_true_label (entry, NULL_TREE);
  gimple_cond_set_false_label (entry, NULL_TREE);
}


/* Called for each element in the hash table (P) as we delete the
   edge to cases hash table.

   Clear all the CASE_CHAINs to prevent problems with copying of
   SWITCH_EXPRs and structure sharing rules, then free the hash table
   element.  */

bool
edge_to_cases_cleanup (edge const &, tree const &value, void *)
{
  tree t, next;

  for (t = value; t; t = next)
    {
      next = CASE_CHAIN (t);
      CASE_CHAIN (t) = NULL;
    }

  return true;
}

/* Start recording information mapping edges to case labels.  */

void
start_recording_case_labels (void)
{
  gcc_assert (edge_to_cases == NULL);
  edge_to_cases = new hash_map<edge, tree>;
  touched_switch_bbs = BITMAP_ALLOC (NULL);
}

/* Return nonzero if we are recording information for case labels.  */

static bool
recording_case_labels_p (void)
{
  return (edge_to_cases != NULL);
}

/* Stop recording information mapping edges to case labels and
   remove any information we have recorded.  */
void
end_recording_case_labels (void)
{
  bitmap_iterator bi;
  unsigned i;
  edge_to_cases->traverse<void *, edge_to_cases_cleanup> (NULL);
  delete edge_to_cases;
  edge_to_cases = NULL;
  EXECUTE_IF_SET_IN_BITMAP (touched_switch_bbs, 0, i, bi)
    {
      basic_block bb = BASIC_BLOCK_FOR_FN (cfun, i);
      if (bb)
	{
	  gimple *stmt = last_stmt (bb);
	  if (stmt && gimple_code (stmt) == GIMPLE_SWITCH)
	    group_case_labels_stmt (as_a <gswitch *> (stmt));
	}
    }
  BITMAP_FREE (touched_switch_bbs);
}

/* If we are inside a {start,end}_recording_cases block, then return
   a chain of CASE_LABEL_EXPRs from T which reference E.

   Otherwise return NULL.  */

tree
get_cases_for_edge (edge e, gswitch *t)
{
  tree *slot;
  size_t i, n;

  /* If we are not recording cases, then we do not have CASE_LABEL_EXPR
     chains available.  Return NULL so the caller can detect this case.  */
  if (!recording_case_labels_p ())
    return NULL;

  slot = edge_to_cases->get (e);
  if (slot)
    return *slot;

  /* If we did not find E in the hash table, then this must be the first
     time we have been queried for information about E & T.  Add all the
     elements from T to the hash table then perform the query again.  */

  n = gimple_switch_num_labels (t);
  for (i = 0; i < n; i++)
    {
      tree elt = gimple_switch_label (t, i);
      tree lab = CASE_LABEL (elt);
      basic_block label_bb = label_to_block (cfun, lab);
      edge this_edge = find_edge (e->src, label_bb);

      /* Add it to the chain of CASE_LABEL_EXPRs referencing E, or create
	 a new chain.  */
      tree &s = edge_to_cases->get_or_insert (this_edge);
      CASE_CHAIN (elt) = s;
      s = elt;
    }

  return *edge_to_cases->get (e);
}

/* Create the edges for a GIMPLE_SWITCH starting at block BB.  */

static void
make_gimple_switch_edges (gswitch *entry, basic_block bb)
{
  size_t i, n;

  n = gimple_switch_num_labels (entry);

  for (i = 0; i < n; ++i)
    {
      basic_block label_bb = gimple_switch_label_bb (cfun, entry, i);
      make_edge (bb, label_bb, 0);
    }
}


/* Return the basic block holding label DEST.  */

basic_block
label_to_block (struct function *ifun, tree dest)
{
  int uid = LABEL_DECL_UID (dest);

  /* We would die hard when faced by an undefined label.  Emit a label to
     the very first basic block.  This will hopefully make even the dataflow
     and undefined variable warnings quite right.  */
  if (seen_error () && uid < 0)
    {
      gimple_stmt_iterator gsi =
	gsi_start_bb (BASIC_BLOCK_FOR_FN (cfun, NUM_FIXED_BLOCKS));
      gimple *stmt;

      stmt = gimple_build_label (dest);
      gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
      uid = LABEL_DECL_UID (dest);
    }
  if (vec_safe_length (ifun->cfg->x_label_to_block_map) <= (unsigned int) uid)
    return NULL;
  return (*ifun->cfg->x_label_to_block_map)[uid];
}

/* Create edges for a goto statement at block BB.  Returns true
   if abnormal edges should be created.  */

static bool
make_goto_expr_edges (basic_block bb)
{
  gimple_stmt_iterator last = gsi_last_bb (bb);
  gimple *goto_t = gsi_stmt (last);

  /* A simple GOTO creates normal edges.  */
  if (simple_goto_p (goto_t))
    {
      tree dest = gimple_goto_dest (goto_t);
      basic_block label_bb = label_to_block (cfun, dest);
      edge e = make_edge (bb, label_bb, EDGE_FALLTHRU);
      e->goto_locus = gimple_location (goto_t);
      gsi_remove (&last, true);
      return false;
    }

  /* A computed GOTO creates abnormal edges.  */
  return true;
}

/* Create edges for an asm statement with labels at block BB.  */

static void
make_gimple_asm_edges (basic_block bb)
{
  gasm *stmt = as_a <gasm *> (last_stmt (bb));
  int i, n = gimple_asm_nlabels (stmt);

  for (i = 0; i < n; ++i)
    {
      tree label = TREE_VALUE (gimple_asm_label_op (stmt, i));
      basic_block label_bb = label_to_block (cfun, label);
      make_edge (bb, label_bb, 0);
    }
}

/*---------------------------------------------------------------------------
			       Flowgraph analysis
---------------------------------------------------------------------------*/

/* Cleanup useless labels in basic blocks.  This is something we wish
   to do early because it allows us to group case labels before creating
   the edges for the CFG, and it speeds up block statement iterators in
   all passes later on.
   We rerun this pass after CFG is created, to get rid of the labels that
   are no longer referenced.  After then we do not run it any more, since
   (almost) no new labels should be created.  */

/* A map from basic block index to the leading label of that block.  */
struct label_record
{
  /* The label.  */
  tree label;

  /* True if the label is referenced from somewhere.  */
  bool used;
};

/* Given LABEL return the first label in the same basic block.  */

static tree
main_block_label (tree label, label_record *label_for_bb)
{
  basic_block bb = label_to_block (cfun, label);
  tree main_label = label_for_bb[bb->index].label;

  /* label_to_block possibly inserted undefined label into the chain.  */
  if (!main_label)
    {
      label_for_bb[bb->index].label = label;
      main_label = label;
    }

  label_for_bb[bb->index].used = true;
  return main_label;
}

/* Clean up redundant labels within the exception tree.  */

static void
cleanup_dead_labels_eh (label_record *label_for_bb)
{
  eh_landing_pad lp;
  eh_region r;
  tree lab;
  int i;

  if (cfun->eh == NULL)
    return;

  for (i = 1; vec_safe_iterate (cfun->eh->lp_array, i, &lp); ++i)
    if (lp && lp->post_landing_pad)
      {
	lab = main_block_label (lp->post_landing_pad, label_for_bb);
	if (lab != lp->post_landing_pad)
	  {
	    EH_LANDING_PAD_NR (lp->post_landing_pad) = 0;
	    lp->post_landing_pad = lab;
	    EH_LANDING_PAD_NR (lab) = lp->index;
	  }
      }

  FOR_ALL_EH_REGION (r)
    switch (r->type)
      {
      case ERT_CLEANUP:
      case ERT_MUST_NOT_THROW:
	break;

      case ERT_TRY:
	{
	  eh_catch c;
	  for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
	    {
	      lab = c->label;
	      if (lab)
		c->label = main_block_label (lab, label_for_bb);
	    }
	}
	break;

      case ERT_ALLOWED_EXCEPTIONS:
	lab = r->u.allowed.label;
	if (lab)
	  r->u.allowed.label = main_block_label (lab, label_for_bb);
	break;
      }
}


/* Cleanup redundant labels.  This is a three-step process:
     1) Find the leading label for each block.
     2) Redirect all references to labels to the leading labels.
     3) Cleanup all useless labels.  */

void
cleanup_dead_labels (void)
{
  basic_block bb;
  label_record *label_for_bb = XCNEWVEC (struct label_record,
					 last_basic_block_for_fn (cfun));

  /* Find a suitable label for each block.  We use the first user-defined
     label if there is one, or otherwise just the first label we see.  */
  FOR_EACH_BB_FN (bb, cfun)
    {
      gimple_stmt_iterator i;

      for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
	{
	  tree label;
	  glabel *label_stmt = dyn_cast <glabel *> (gsi_stmt (i));

	  if (!label_stmt)
	    break;

	  label = gimple_label_label (label_stmt);

	  /* If we have not yet seen a label for the current block,
	     remember this one and see if there are more labels.  */
	  if (!label_for_bb[bb->index].label)
	    {
	      label_for_bb[bb->index].label = label;
	      continue;
	    }

	  /* If we did see a label for the current block already, but it
	     is an artificially created label, replace it if the current
	     label is a user defined label.  */
	  if (!DECL_ARTIFICIAL (label)
	      && DECL_ARTIFICIAL (label_for_bb[bb->index].label))
	    {
	      label_for_bb[bb->index].label = label;
	      break;
	    }
	}
    }

  /* Now redirect all jumps/branches to the selected label.
     First do so for each block ending in a control statement.  */
  FOR_EACH_BB_FN (bb, cfun)
    {
      gimple *stmt = last_stmt (bb);
      tree label, new_label;

      if (!stmt)
	continue;

      switch (gimple_code (stmt))
	{
	case GIMPLE_COND:
	  {
	    gcond *cond_stmt = as_a <gcond *> (stmt);
	    label = gimple_cond_true_label (cond_stmt);
	    if (label)
	      {
		new_label = main_block_label (label, label_for_bb);
		if (new_label != label)
		  gimple_cond_set_true_label (cond_stmt, new_label);
	      }

	    label = gimple_cond_false_label (cond_stmt);
	    if (label)
	      {
		new_label = main_block_label (label, label_for_bb);
		if (new_label != label)
		  gimple_cond_set_false_label (cond_stmt, new_label);
	      }
	  }
	  break;

	case GIMPLE_SWITCH:
	  {
	    gswitch *switch_stmt = as_a <gswitch *> (stmt);
	    size_t i, n = gimple_switch_num_labels (switch_stmt);

	    /* Replace all destination labels.  */
	    for (i = 0; i < n; ++i)
	      {
		tree case_label = gimple_switch_label (switch_stmt, i);
		label = CASE_LABEL (case_label);
		new_label = main_block_label (label, label_for_bb);
		if (new_label != label)
		  CASE_LABEL (case_label) = new_label;
	      }
	    break;
	  }

	case GIMPLE_ASM:
	  {
	    gasm *asm_stmt = as_a <gasm *> (stmt);
	    int i, n = gimple_asm_nlabels (asm_stmt);

	    for (i = 0; i < n; ++i)
	      {
		tree cons = gimple_asm_label_op (asm_stmt, i);
		tree label = main_block_label (TREE_VALUE (cons), label_for_bb);
		TREE_VALUE (cons) = label;
	      }
	    break;
	  }

	/* We have to handle gotos until they're removed, and we don't
	   remove them until after we've created the CFG edges.  */
	case GIMPLE_GOTO:
	  if (!computed_goto_p (stmt))
	    {
	      ggoto *goto_stmt = as_a <ggoto *> (stmt);
	      label = gimple_goto_dest (goto_stmt);
	      new_label = main_block_label (label, label_for_bb);
	      if (new_label != label)
		gimple_goto_set_dest (goto_stmt, new_label);
	    }
	  break;

	case GIMPLE_TRANSACTION:
	  {
	    gtransaction *txn = as_a <gtransaction *> (stmt);

	    label = gimple_transaction_label_norm (txn);
	    if (label)
	      {
		new_label = main_block_label (label, label_for_bb);
		if (new_label != label)
		  gimple_transaction_set_label_norm (txn, new_label);
	      }

	    label = gimple_transaction_label_uninst (txn);
	    if (label)
	      {
		new_label = main_block_label (label, label_for_bb);
		if (new_label != label)
		  gimple_transaction_set_label_uninst (txn, new_label);
	      }

	    label = gimple_transaction_label_over (txn);
	    if (label)
	      {
		new_label = main_block_label (label, label_for_bb);
		if (new_label != label)
		  gimple_transaction_set_label_over (txn, new_label);
	      }
	  }
	  break;

	default:
	  break;
      }
    }

  /* Do the same for the exception region tree labels.  */
  cleanup_dead_labels_eh (label_for_bb);

  /* Finally, purge dead labels.  All user-defined labels and labels that
     can be the target of non-local gotos and labels which have their
     address taken are preserved.  */
  FOR_EACH_BB_FN (bb, cfun)
    {
      gimple_stmt_iterator i;
      tree label_for_this_bb = label_for_bb[bb->index].label;

      if (!label_for_this_bb)
	continue;

      /* If the main label of the block is unused, we may still remove it.  */
      if (!label_for_bb[bb->index].used)
	label_for_this_bb = NULL;

      for (i = gsi_start_bb (bb); !gsi_end_p (i); )
	{
	  tree label;
	  glabel *label_stmt = dyn_cast <glabel *> (gsi_stmt (i));

	  if (!label_stmt)
	    break;

	  label = gimple_label_label (label_stmt);

	  if (label == label_for_this_bb
	      || !DECL_ARTIFICIAL (label)
	      || DECL_NONLOCAL (label)
	      || FORCED_LABEL (label))
	    gsi_next (&i);
	  else
	    {
	      gcc_checking_assert (EH_LANDING_PAD_NR (label) == 0);
	      gsi_remove (&i, true);
	    }
	}
    }

  free (label_for_bb);
}

/* Scan the sorted vector of cases in STMT (a GIMPLE_SWITCH) and combine
   the ones jumping to the same label.
   Eg. three separate entries 1: 2: 3: become one entry 1..3:  */

bool
group_case_labels_stmt (gswitch *stmt)
{
  int old_size = gimple_switch_num_labels (stmt);
  int i, next_index, new_size;
  basic_block default_bb = NULL;
  hash_set<tree> *removed_labels = NULL;

  default_bb = gimple_switch_default_bb (cfun, stmt);

  /* Look for possible opportunities to merge cases.  */
  new_size = i = 1;
  while (i < old_size)
    {
      tree base_case, base_high;
      basic_block base_bb;

      base_case = gimple_switch_label (stmt, i);

      gcc_assert (base_case);
      base_bb = label_to_block (cfun, CASE_LABEL (base_case));

      /* Discard cases that have the same destination as the default case or
	 whose destination blocks have already been removed as unreachable.  */
      if (base_bb == NULL
	  || base_bb == default_bb
	  || (removed_labels
	      && removed_labels->contains (CASE_LABEL (base_case))))
	{
	  i++;
	  continue;
	}

      base_high = CASE_HIGH (base_case)
	  ? CASE_HIGH (base_case)
	  : CASE_LOW (base_case);
      next_index = i + 1;

      /* Try to merge case labels.  Break out when we reach the end
	 of the label vector or when we cannot merge the next case
	 label with the current one.  */
      while (next_index < old_size)
	{
	  tree merge_case = gimple_switch_label (stmt, next_index);
	  basic_block merge_bb = label_to_block (cfun, CASE_LABEL (merge_case));
	  wide_int bhp1 = wi::to_wide (base_high) + 1;

	  /* Merge the cases if they jump to the same place,
	     and their ranges are consecutive.  */
	  if (merge_bb == base_bb
	      && (removed_labels == NULL
		  || !removed_labels->contains (CASE_LABEL (merge_case)))
	      && wi::to_wide (CASE_LOW (merge_case)) == bhp1)
	    {
	      base_high
		= (CASE_HIGH (merge_case)
		   ? CASE_HIGH (merge_case) : CASE_LOW (merge_case));
	      CASE_HIGH (base_case) = base_high;
	      next_index++;
	    }
	  else
	    break;
	}

      /* Discard cases that have an unreachable destination block.  */
      if (EDGE_COUNT (base_bb->succs) == 0
	  && gimple_seq_unreachable_p (bb_seq (base_bb))
	  /* Don't optimize this if __builtin_unreachable () is the
	     implicitly added one by the C++ FE too early, before
	     -Wreturn-type can be diagnosed.  We'll optimize it later
	     during switchconv pass or any other cfg cleanup.  */
	  && (gimple_in_ssa_p (cfun)
	      || (LOCATION_LOCUS (gimple_location (last_stmt (base_bb)))
		  != BUILTINS_LOCATION)))
	{
	  edge base_edge = find_edge (gimple_bb (stmt), base_bb);
	  if (base_edge != NULL)
	    {
	      for (gimple_stmt_iterator gsi = gsi_start_bb (base_bb);
		   !gsi_end_p (gsi); gsi_next (&gsi))
		if (glabel *stmt = dyn_cast <glabel *> (gsi_stmt (gsi)))
		  {
		    if (FORCED_LABEL (gimple_label_label (stmt))
			|| DECL_NONLOCAL (gimple_label_label (stmt)))
		      {
			/* Forced/non-local labels aren't going to be removed,
			   but they will be moved to some neighbouring basic
			   block. If some later case label refers to one of
			   those labels, we should throw that case away rather
			   than keeping it around and refering to some random
			   other basic block without an edge to it.  */
			if (removed_labels == NULL)
			  removed_labels = new hash_set<tree>;
			removed_labels->add (gimple_label_label (stmt));
		      }
		  }
		else
		  break;
	      remove_edge_and_dominated_blocks (base_edge);
	    }
	  i = next_index;
	  continue;
	}

      if (new_size < i)
	gimple_switch_set_label (stmt, new_size,
				 gimple_switch_label (stmt, i));
      i = next_index;
      new_size++;
    }

  gcc_assert (new_size <= old_size);

  if (new_size < old_size)
    gimple_switch_set_num_labels (stmt, new_size);

  delete removed_labels;
  return new_size < old_size;
}

/* Look for blocks ending in a multiway branch (a GIMPLE_SWITCH),
   and scan the sorted vector of cases.  Combine the ones jumping to the
   same label.  */

bool
group_case_labels (void)
{
  basic_block bb;
  bool changed = false;

  FOR_EACH_BB_FN (bb, cfun)
    {
      gimple *stmt = last_stmt (bb);
      if (stmt && gimple_code (stmt) == GIMPLE_SWITCH)
	changed |= group_case_labels_stmt (as_a <gswitch *> (stmt));
    }

  return changed;
}

/* Checks whether we can merge block B into block A.  */

static bool
gimple_can_merge_blocks_p (basic_block a, basic_block b)
{
  gimple *stmt;

  if (!single_succ_p (a))
    return false;

  if (single_succ_edge (a)->flags & EDGE_COMPLEX)
    return false;

  if (single_succ (a) != b)
    return false;

  if (!single_pred_p (b))
    return false;

  if (a == ENTRY_BLOCK_PTR_FOR_FN (cfun)
      || b == EXIT_BLOCK_PTR_FOR_FN (cfun))
    return false;

  /* If A ends by a statement causing exceptions or something similar, we
     cannot merge the blocks.  */
  stmt = last_stmt (a);
  if (stmt && stmt_ends_bb_p (stmt))
    return false;

  /* Do not allow a block with only a non-local label to be merged.  */
  if (stmt)
    if (glabel *label_stmt = dyn_cast <glabel *> (stmt))
      if (DECL_NONLOCAL (gimple_label_label (label_stmt)))
	return false;

  /* Examine the labels at the beginning of B.  */
  for (gimple_stmt_iterator gsi = gsi_start_bb (b); !gsi_end_p (gsi);
       gsi_next (&gsi))
    {
      tree lab;
      glabel *label_stmt = dyn_cast <glabel *> (gsi_stmt (gsi));
      if (!label_stmt)
	break;
      lab = gimple_label_label (label_stmt);

      /* Do not remove user forced labels or for -O0 any user labels.  */
      if (!DECL_ARTIFICIAL (lab) && (!optimize || FORCED_LABEL (lab)))
	return false;
    }

  /* Protect simple loop latches.  We only want to avoid merging
     the latch with the loop header or with a block in another
     loop in this case.  */
  if (current_loops
      && b->loop_father->latch == b
      && loops_state_satisfies_p (LOOPS_HAVE_SIMPLE_LATCHES)
      && (b->loop_father->header == a
	  || b->loop_father != a->loop_father))
    return false;

  /* It must be possible to eliminate all phi nodes in B.  If ssa form
     is not up-to-date and a name-mapping is registered, we cannot eliminate
     any phis.  Symbols marked for renaming are never a problem though.  */
  for (gphi_iterator gsi = gsi_start_phis (b); !gsi_end_p (gsi);
       gsi_next (&gsi))
    {
      gphi *phi = gsi.phi ();
      /* Technically only new names matter.  */
      if (name_registered_for_update_p (PHI_RESULT (phi)))
	return false;
    }

  /* When not optimizing, don't merge if we'd lose goto_locus.  */
  if (!optimize
      && single_succ_edge (a)->goto_locus != UNKNOWN_LOCATION)
    {
      location_t goto_locus = single_succ_edge (a)->goto_locus;
      gimple_stmt_iterator prev, next;
      prev = gsi_last_nondebug_bb (a);
      next = gsi_after_labels (b);
      if (!gsi_end_p (next) && is_gimple_debug (gsi_stmt (next)))
	gsi_next_nondebug (&next);
      if ((gsi_end_p (prev)
	   || gimple_location (gsi_stmt (prev)) != goto_locus)
	  && (gsi_end_p (next)
	      || gimple_location (gsi_stmt (next)) != goto_locus))
	return false;
    }

  return true;
}

/* Replaces all uses of NAME by VAL.  */

void
replace_uses_by (tree name, tree val)
{
  imm_use_iterator imm_iter;
  use_operand_p use;
  gimple *stmt;
  edge e;

  FOR_EACH_IMM_USE_STMT (stmt, imm_iter, name)
    {
      /* Mark the block if we change the last stmt in it.  */
      if (cfgcleanup_altered_bbs
	  && stmt_ends_bb_p (stmt))
	bitmap_set_bit (cfgcleanup_altered_bbs, gimple_bb (stmt)->index);

      FOR_EACH_IMM_USE_ON_STMT (use, imm_iter)
        {
	  replace_exp (use, val);

	  if (gimple_code (stmt) == GIMPLE_PHI)
	    {
	      e = gimple_phi_arg_edge (as_a <gphi *> (stmt),
				       PHI_ARG_INDEX_FROM_USE (use));
	      if (e->flags & EDGE_ABNORMAL
		  && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val))
		{
		  /* This can only occur for virtual operands, since
		     for the real ones SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name))
		     would prevent replacement.  */
		  gcc_checking_assert (virtual_operand_p (name));
		  SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val) = 1;
		}
	    }
	}

      if (gimple_code (stmt) != GIMPLE_PHI)
	{
	  gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
	  gimple *orig_stmt = stmt;
	  size_t i;

	  /* FIXME.  It shouldn't be required to keep TREE_CONSTANT
	     on ADDR_EXPRs up-to-date on GIMPLE.  Propagation will
	     only change sth from non-invariant to invariant, and only
	     when propagating constants.  */
	  if (is_gimple_min_invariant (val))
	    for (i = 0; i < gimple_num_ops (stmt); i++)
	      {
		tree op = gimple_op (stmt, i);
		/* Operands may be empty here.  For example, the labels
		   of a GIMPLE_COND are nulled out following the creation
		   of the corresponding CFG edges.  */
		if (op && TREE_CODE (op) == ADDR_EXPR)
		  recompute_tree_invariant_for_addr_expr (op);
	      }

	  if (fold_stmt (&gsi))
	    stmt = gsi_stmt (gsi);

	  if (maybe_clean_or_replace_eh_stmt (orig_stmt, stmt))
	    gimple_purge_dead_eh_edges (gimple_bb (stmt));

	  update_stmt (stmt);
	}
    }

  gcc_checking_assert (has_zero_uses (name));

  /* Also update the trees stored in loop structures.  */
  if (current_loops)
    {
      for (auto loop : loops_list (cfun, 0))
	  substitute_in_loop_info (loop, name, val);
    }
}

/* Merge block B into block A.  */

static void
gimple_merge_blocks (basic_block a, basic_block b)
{
  gimple_stmt_iterator last, gsi;
  gphi_iterator psi;

  if (dump_file)
    fprintf (dump_file, "Merging blocks %d and %d\n", a->index, b->index);

  /* Remove all single-valued PHI nodes from block B of the form
     V_i = PHI <V_j> by propagating V_j to all the uses of V_i.  */
  gsi = gsi_last_bb (a);
  for (psi = gsi_start_phis (b); !gsi_end_p (psi); )
    {
      gimple *phi = gsi_stmt (psi);
      tree def = gimple_phi_result (phi), use = gimple_phi_arg_def (phi, 0);
      gimple *copy;
      bool may_replace_uses = (virtual_operand_p (def)
			       || may_propagate_copy (def, use));

      /* In case we maintain loop closed ssa form, do not propagate arguments
	 of loop exit phi nodes.  */
      if (current_loops
	  && loops_state_satisfies_p (LOOP_CLOSED_SSA)
	  && !virtual_operand_p (def)
	  && TREE_CODE (use) == SSA_NAME
	  && a->loop_father != b->loop_father)
	may_replace_uses = false;

      if (!may_replace_uses)
	{
	  gcc_assert (!virtual_operand_p (def));

	  /* Note that just emitting the copies is fine -- there is no problem
	     with ordering of phi nodes.  This is because A is the single
	     predecessor of B, therefore results of the phi nodes cannot
	     appear as arguments of the phi nodes.  */
	  copy = gimple_build_assign (def, use);
	  gsi_insert_after (&gsi, copy, GSI_NEW_STMT);
          remove_phi_node (&psi, false);
	}
      else
        {
	  /* If we deal with a PHI for virtual operands, we can simply
	     propagate these without fussing with folding or updating
	     the stmt.  */
	  if (virtual_operand_p (def))
	    {
	      imm_use_iterator iter;
	      use_operand_p use_p;
	      gimple *stmt;

	      FOR_EACH_IMM_USE_STMT (stmt, iter, def)
		FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
		  SET_USE (use_p, use);

	      if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def))
		SSA_NAME_OCCURS_IN_ABNORMAL_PHI (use) = 1;
	    }
	  else
            replace_uses_by (def, use);

          remove_phi_node (&psi, true);
        }
    }

  /* Ensure that B follows A.  */
  move_block_after (b, a);

  gcc_assert (single_succ_edge (a)->flags & EDGE_FALLTHRU);
  gcc_assert (!last_stmt (a) || !stmt_ends_bb_p (last_stmt (a)));

  /* Remove labels from B and set gimple_bb to A for other statements.  */
  for (gsi = gsi_start_bb (b); !gsi_end_p (gsi);)
    {
      gimple *stmt = gsi_stmt (gsi);
      if (glabel *label_stmt = dyn_cast <glabel *> (stmt))
	{
	  tree label = gimple_label_label (label_stmt);
	  int lp_nr;

	  gsi_remove (&gsi, false);

	  /* Now that we can thread computed gotos, we might have
	     a situation where we have a forced label in block B
	     However, the label at the start of block B might still be
	     used in other ways (think about the runtime checking for
	     Fortran assigned gotos).  So we cannot just delete the
	     label.  Instead we move the label to the start of block A.  */
	  if (FORCED_LABEL (label))
	    {
	      gimple_stmt_iterator dest_gsi = gsi_start_bb (a);
	      tree first_label = NULL_TREE;
	      if (!gsi_end_p (dest_gsi))
		if (glabel *first_label_stmt
		    = dyn_cast <glabel *> (gsi_stmt (dest_gsi)))
		  first_label = gimple_label_label (first_label_stmt);
	      if (first_label
		  && (DECL_NONLOCAL (first_label)
		      || EH_LANDING_PAD_NR (first_label) != 0))
		gsi_insert_after (&dest_gsi, stmt, GSI_NEW_STMT);
	      else
		gsi_insert_before (&dest_gsi, stmt, GSI_NEW_STMT);
	    }
	  /* Other user labels keep around in a form of a debug stmt.  */
	  else if (!DECL_ARTIFICIAL (label) && MAY_HAVE_DEBUG_BIND_STMTS)
	    {
	      gimple *dbg = gimple_build_debug_bind (label,
						     integer_zero_node,
						     stmt);
	      gimple_debug_bind_reset_value (dbg);
	      gsi_insert_before (&gsi, dbg, GSI_SAME_STMT);
	    }

	  lp_nr = EH_LANDING_PAD_NR (label);
	  if (lp_nr)
	    {
	      eh_landing_pad lp = get_eh_landing_pad_from_number (lp_nr);
	      lp->post_landing_pad = NULL;
	    }
	}
      else
	{
	  gimple_set_bb (stmt, a);
	  gsi_next (&gsi);
	}
    }

  /* When merging two BBs, if their counts are different, the larger count
     is selected as the new bb count. This is to handle inconsistent
     profiles.  */
  if (a->loop_father == b->loop_father)
    {
      a->count = a->count.merge (b->count);
    }

  /* Merge the sequences.  */
  last = gsi_last_bb (a);
  gsi_insert_seq_after (&last, bb_seq (b), GSI_NEW_STMT);
  set_bb_seq (b, NULL);

  if (cfgcleanup_altered_bbs)
    bitmap_set_bit (cfgcleanup_altered_bbs, a->index);
}


/* Return the one of two successors of BB that is not reachable by a
   complex edge, if there is one.  Else, return BB.  We use
   this in optimizations that use post-dominators for their heuristics,
   to catch the cases in C++ where function calls are involved.  */

basic_block
single_noncomplex_succ (basic_block bb)
{
  edge e0, e1;
  if (EDGE_COUNT (bb->succs) != 2)
    return bb;

  e0 = EDGE_SUCC (bb, 0);
  e1 = EDGE_SUCC (bb, 1);
  if (e0->flags & EDGE_COMPLEX)
    return e1->dest;
  if (e1->flags & EDGE_COMPLEX)
    return e0->dest;

  return bb;
}

/* T is CALL_EXPR.  Set current_function_calls_* flags.  */

void
notice_special_calls (gcall *call)
{
  int flags = gimple_call_flags (call);

  if (flags & ECF_MAY_BE_ALLOCA)
    cfun->calls_alloca = true;
  if (flags & ECF_RETURNS_TWICE)
    cfun->calls_setjmp = true;
}


/* Clear flags set by notice_special_calls.  Used by dead code removal
   to update the flags.  */

void
clear_special_calls (void)
{
  cfun->calls_alloca = false;
  cfun->calls_setjmp = false;
}

/* Remove PHI nodes associated with basic block BB and all edges out of BB.  */

static void
remove_phi_nodes_and_edges_for_unreachable_block (basic_block bb)
{
  /* Since this block is no longer reachable, we can just delete all
     of its PHI nodes.  */
  remove_phi_nodes (bb);

  /* Remove edges to BB's successors.  */
  while (EDGE_COUNT (bb->succs) > 0)
    remove_edge (EDGE_SUCC (bb, 0));
}


/* Remove statements of basic block BB.  */

static void
remove_bb (basic_block bb)
{
  gimple_stmt_iterator i;

  if (dump_file)
    {
      fprintf (dump_file, "Removing basic block %d\n", bb->index);
      if (dump_flags & TDF_DETAILS)
	{
	  dump_bb (dump_file, bb, 0, TDF_BLOCKS);
	  fprintf (dump_file, "\n");
	}
    }

  if (current_loops)
    {
      class loop *loop = bb->loop_father;

      /* If a loop gets removed, clean up the information associated
	 with it.  */
      if (loop->latch == bb
	  || loop->header == bb)
	free_numbers_of_iterations_estimates (loop);
    }

  /* Remove all the instructions in the block.  */
  if (bb_seq (bb) != NULL)
    {
      /* Walk backwards so as to get a chance to substitute all
	 released DEFs into debug stmts.  See
	 eliminate_unnecessary_stmts() in tree-ssa-dce.cc for more
	 details.  */
      for (i = gsi_last_bb (bb); !gsi_end_p (i);)
	{
	  gimple *stmt = gsi_stmt (i);
	  glabel *label_stmt = dyn_cast <glabel *> (stmt);
	  if (label_stmt
	      && (FORCED_LABEL (gimple_label_label (label_stmt))
		  || DECL_NONLOCAL (gimple_label_label (label_stmt))))
	    {
	      basic_block new_bb;
	      gimple_stmt_iterator new_gsi;

	      /* A non-reachable non-local label may still be referenced.
		 But it no longer needs to carry the extra semantics of
		 non-locality.  */
	      if (DECL_NONLOCAL (gimple_label_label (label_stmt)))
		{
		  DECL_NONLOCAL (gimple_label_label (label_stmt)) = 0;
		  FORCED_LABEL (gimple_label_label (label_stmt)) = 1;
		}

	      new_bb = bb->prev_bb;
	      /* Don't move any labels into ENTRY block.  */
	      if (new_bb == ENTRY_BLOCK_PTR_FOR_FN (cfun))
		{
		  new_bb = single_succ (new_bb);
		  gcc_assert (new_bb != bb);
		}
	      if ((unsigned) bb->index < bb_to_omp_idx.length ()
		  && ((unsigned) new_bb->index >= bb_to_omp_idx.length ()
		      || (bb_to_omp_idx[bb->index]
			  != bb_to_omp_idx[new_bb->index])))
		{
		  /* During cfg pass make sure to put orphaned labels
		     into the right OMP region.  */
		  unsigned int i;
		  int idx;
		  new_bb = NULL;
		  FOR_EACH_VEC_ELT (bb_to_omp_idx, i, idx)
		    if (i >= NUM_FIXED_BLOCKS
			&& idx == bb_to_omp_idx[bb->index]
			&& i != (unsigned) bb->index)
		      {
			new_bb = BASIC_BLOCK_FOR_FN (cfun, i);
			break;
		      }
		  if (new_bb == NULL)
		    {
		      new_bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
		      gcc_assert (new_bb != bb);
		    }
		}
	      new_gsi = gsi_after_labels (new_bb);
	      gsi_remove (&i, false);
	      gsi_insert_before (&new_gsi, stmt, GSI_NEW_STMT);
	    }
	  else
	    {
	      /* Release SSA definitions.  */
	      release_defs (stmt);
	      gsi_remove (&i, true);
	    }

	  if (gsi_end_p (i))
	    i = gsi_last_bb (bb);
	  else
	    gsi_prev (&i);
	}
    }

  if ((unsigned) bb->index < bb_to_omp_idx.length ())
    bb_to_omp_idx[bb->index] = -1;
  remove_phi_nodes_and_edges_for_unreachable_block (bb);
  bb->il.gimple.seq = NULL;
  bb->il.gimple.phi_nodes = NULL;
}


/* Given a basic block BB and a value VAL for use in the final statement
   of the block (if a GIMPLE_COND, GIMPLE_SWITCH, or computed goto), return
   the edge that will be taken out of the block.
   If VAL is NULL_TREE, then the current value of the final statement's
   predicate or index is used.
   If the value does not match a unique edge, NULL is returned.  */

edge
find_taken_edge (basic_block bb, tree val)
{
  gimple *stmt;

  stmt = last_stmt (bb);

  /* Handle ENTRY and EXIT.  */
  if (!stmt)
    return NULL;

  if (gimple_code (stmt) == GIMPLE_COND)
    return find_taken_edge_cond_expr (as_a <gcond *> (stmt), val);

  if (gimple_code (stmt) == GIMPLE_SWITCH)
    return find_taken_edge_switch_expr (as_a <gswitch *> (stmt), val);

  if (computed_goto_p (stmt))
    {
      /* Only optimize if the argument is a label, if the argument is
	 not a label then we cannot construct a proper CFG.

         It may be the case that we only need to allow the LABEL_REF to
         appear inside an ADDR_EXPR, but we also allow the LABEL_REF to
         appear inside a LABEL_EXPR just to be safe.  */
      if (val
	  && (TREE_CODE (val) == ADDR_EXPR || TREE_CODE (val) == LABEL_EXPR)
	  && TREE_CODE (TREE_OPERAND (val, 0)) == LABEL_DECL)
	return find_taken_edge_computed_goto (bb, TREE_OPERAND (val, 0));
    }

  /* Otherwise we only know the taken successor edge if it's unique.  */
  return single_succ_p (bb) ? single_succ_edge (bb) : NULL;
}

/* Given a constant value VAL and the entry block BB to a GOTO_EXPR
   statement, determine which of the outgoing edges will be taken out of the
   block.  Return NULL if either edge may be taken.  */

static edge
find_taken_edge_computed_goto (basic_block bb, tree val)
{
  basic_block dest;
  edge e = NULL;

  dest = label_to_block (cfun, val);
  if (dest)
    e = find_edge (bb, dest);

  /* It's possible for find_edge to return NULL here on invalid code
     that abuses the labels-as-values extension (e.g. code that attempts to
     jump *between* functions via stored labels-as-values; PR 84136).
     If so, then we simply return that NULL for the edge.
     We don't currently have a way of detecting such invalid code, so we
     can't assert that it was the case when a NULL edge occurs here.  */

  return e;
}

/* Given COND_STMT and a constant value VAL for use as the predicate,
   determine which of the two edges will be taken out of
   the statement's block.  Return NULL if either edge may be taken.
   If VAL is NULL_TREE, then the current value of COND_STMT's predicate
   is used.  */

static edge
find_taken_edge_cond_expr (const gcond *cond_stmt, tree val)
{
  edge true_edge, false_edge;

  if (val == NULL_TREE)
    {
      /* Use the current value of the predicate.  */
      if (gimple_cond_true_p (cond_stmt))
	val = integer_one_node;
      else if (gimple_cond_false_p (cond_stmt))
	val = integer_zero_node;
      else
	return NULL;
    }
  else if (TREE_CODE (val) != INTEGER_CST)
    return NULL;

  extract_true_false_edges_from_block (gimple_bb (cond_stmt),
				       &true_edge, &false_edge);

  return (integer_zerop (val) ? false_edge : true_edge);
}

/* Given SWITCH_STMT and an INTEGER_CST VAL for use as the index, determine
   which edge will be taken out of the statement's block.  Return NULL if any
   edge may be taken.
   If VAL is NULL_TREE, then the current value of SWITCH_STMT's index
   is used.  */

edge
find_taken_edge_switch_expr (const gswitch *switch_stmt, tree val)
{
  basic_block dest_bb;
  edge e;
  tree taken_case;

  if (gimple_switch_num_labels (switch_stmt) == 1)
    taken_case = gimple_switch_default_label (switch_stmt);
  else
    {
      if (val == NULL_TREE)
	val = gimple_switch_index (switch_stmt);
      if (TREE_CODE (val) != INTEGER_CST)
	return NULL;
      else
	taken_case = find_case_label_for_value (switch_stmt, val);
    }
  dest_bb = label_to_block (cfun, CASE_LABEL (taken_case));

  e = find_edge (gimple_bb (switch_stmt), dest_bb);
  gcc_assert (e);
  return e;
}


/* Return the CASE_LABEL_EXPR that SWITCH_STMT will take for VAL.
   We can make optimal use here of the fact that the case labels are
   sorted: We can do a binary search for a case matching VAL.  */

tree
find_case_label_for_value (const gswitch *switch_stmt, tree val)
{
  size_t low, high, n = gimple_switch_num_labels (switch_stmt);
  tree default_case = gimple_switch_default_label (switch_stmt);

  for (low = 0, high = n; high - low > 1; )
    {
      size_t i = (high + low) / 2;
      tree t = gimple_switch_label (switch_stmt, i);
      int cmp;

      /* Cache the result of comparing CASE_LOW and val.  */
      cmp = tree_int_cst_compare (CASE_LOW (t), val);

      if (cmp > 0)
	high = i;
      else
	low = i;

      if (CASE_HIGH (t) == NULL)
	{
	  /* A singe-valued case label.  */
	  if (cmp == 0)
	    return t;
	}
      else
	{
	  /* A case range.  We can only handle integer ranges.  */
	  if (cmp <= 0 && tree_int_cst_compare (CASE_HIGH (t), val) >= 0)
	    return t;
	}
    }

  return default_case;
}


/* Dump a basic block on stderr.  */

void
gimple_debug_bb (basic_block bb)
{
  dump_bb (stderr, bb, 0, TDF_VOPS|TDF_MEMSYMS|TDF_BLOCKS);
}


/* Dump basic block with index N on stderr.  */

basic_block
gimple_debug_bb_n (int n)
{
  gimple_debug_bb (BASIC_BLOCK_FOR_FN (cfun, n));
  return BASIC_BLOCK_FOR_FN (cfun, n);
}


/* Dump the CFG on stderr.

   FLAGS are the same used by the tree dumping functions
   (see TDF_* in dumpfile.h).  */

void
gimple_debug_cfg (dump_flags_t flags)
{
  gimple_dump_cfg (stderr, flags);
}


/* Dump the program showing basic block boundaries on the given FILE.

   FLAGS are the same used by the tree dumping functions (see TDF_* in
   tree.h).  */

void
gimple_dump_cfg (FILE *file, dump_flags_t flags)
{
  if (flags & TDF_DETAILS)
    {
      dump_function_header (file, current_function_decl, flags);
      fprintf (file, ";; \n%d basic blocks, %d edges, last basic block %d.\n\n",
	       n_basic_blocks_for_fn (cfun), n_edges_for_fn (cfun),
	       last_basic_block_for_fn (cfun));

      brief_dump_cfg (file, flags);
      fprintf (file, "\n");
    }

  if (flags & TDF_STATS)
    dump_cfg_stats (file);

  dump_function_to_file (current_function_decl, file, flags | TDF_BLOCKS);
}


/* Dump CFG statistics on FILE.  */

void
dump_cfg_stats (FILE *file)
{
  static long max_num_merged_labels = 0;
  unsigned long size, total = 0;
  long num_edges;
  basic_block bb;
  const char * const fmt_str   = "%-30s%-13s%12s\n";
  const char * const fmt_str_1 = "%-30s%13d" PRsa (11) "\n";
  const char * const fmt_str_2 = "%-30s%13ld" PRsa (11) "\n";
  const char * const fmt_str_3 = "%-43s" PRsa (11) "\n";
  const char *funcname = current_function_name ();

  fprintf (file, "\nCFG Statistics for %s\n\n", funcname);

  fprintf (file, "---------------------------------------------------------\n");
  fprintf (file, fmt_str, "", "  Number of  ", "Memory");
  fprintf (file, fmt_str, "", "  instances  ", "used ");
  fprintf (file, "---------------------------------------------------------\n");

  size = n_basic_blocks_for_fn (cfun) * sizeof (struct basic_block_def);
  total += size;
  fprintf (file, fmt_str_1, "Basic blocks", n_basic_blocks_for_fn (cfun),
	   SIZE_AMOUNT (size));

  num_edges = 0;
  FOR_EACH_BB_FN (bb, cfun)
    num_edges += EDGE_COUNT (bb->succs);
  size = num_edges * sizeof (class edge_def);
  total += size;
  fprintf (file, fmt_str_2, "Edges", num_edges, SIZE_AMOUNT (size));

  fprintf (file, "---------------------------------------------------------\n");
  fprintf (file, fmt_str_3, "Total memory used by CFG data",
	   SIZE_AMOUNT (total));
  fprintf (file, "---------------------------------------------------------\n");
  fprintf (file, "\n");

  if (cfg_stats.num_merged_labels > max_num_merged_labels)
    max_num_merged_labels = cfg_stats.num_merged_labels;

  fprintf (file, "Coalesced label blocks: %ld (Max so far: %ld)\n",
	   cfg_stats.num_merged_labels, max_num_merged_labels);

  fprintf (file, "\n");
}


/* Dump CFG statistics on stderr.  Keep extern so that it's always
   linked in the final executable.  */

DEBUG_FUNCTION void
debug_cfg_stats (void)
{
  dump_cfg_stats (stderr);
}

/*---------------------------------------------------------------------------
			     Miscellaneous helpers
---------------------------------------------------------------------------*/

/* Return true if T, a GIMPLE_CALL, can make an abnormal transfer of control
   flow.  Transfers of control flow associated with EH are excluded.  */

static bool
call_can_make_abnormal_goto (gimple *t)
{
  /* If the function has no non-local labels, then a call cannot make an
     abnormal transfer of control.  */
  if (!cfun->has_nonlocal_label
      && !cfun->calls_setjmp)
   return false;

  /* Likewise if the call has no side effects.  */
  if (!gimple_has_side_effects (t))
    return false;

  /* Likewise if the called function is leaf.  */
  if (gimple_call_flags (t) & ECF_LEAF)
    return false;

  return true;
}


/* Return true if T can make an abnormal transfer of control flow.
   Transfers of control flow associated with EH are excluded.  */

bool
stmt_can_make_abnormal_goto (gimple *t)
{
  if (computed_goto_p (t))
    return true;
  if (is_gimple_call (t))
    return call_can_make_abnormal_goto (t);
  return false;
}


/* Return true if T represents a stmt that always transfers control.  */

bool
is_ctrl_stmt (gimple *t)
{
  switch (gimple_code (t))
    {
    case GIMPLE_COND:
    case GIMPLE_SWITCH:
    case GIMPLE_GOTO:
    case GIMPLE_RETURN:
    case GIMPLE_RESX:
      return true;
    default:
      return false;
    }
}


/* Return true if T is a statement that may alter the flow of control
   (e.g., a call to a non-returning function).  */

bool
is_ctrl_altering_stmt (gimple *t)
{
  gcc_assert (t);

  switch (gimple_code (t))
    {
    case GIMPLE_CALL:
      /* Per stmt call flag indicates whether the call could alter
	 controlflow.  */
      if (gimple_call_ctrl_altering_p (t))
	return true;
      break;

    case GIMPLE_EH_DISPATCH:
      /* EH_DISPATCH branches to the individual catch handlers at
	 this level of a try or allowed-exceptions region.  It can
	 fallthru to the next statement as well.  */
      return true;

    case GIMPLE_ASM:
      if (gimple_asm_nlabels (as_a <gasm *> (t)) > 0)
	return true;
      break;

    CASE_GIMPLE_OMP:
      /* OpenMP directives alter control flow.  */
      return true;

    case GIMPLE_TRANSACTION:
      /* A transaction start alters control flow.  */
      return true;

    default:
      break;
    }

  /* If a statement can throw, it alters control flow.  */
  return stmt_can_throw_internal (cfun, t);
}


/* Return true if T is a simple local goto.  */

bool
simple_goto_p (gimple *t)
{
  return (gimple_code (t) == GIMPLE_GOTO
	  && TREE_CODE (gimple_goto_dest (t)) == LABEL_DECL);
}


/* Return true if STMT should start a new basic block.  PREV_STMT is
   the statement preceding STMT.  It is used when STMT is a label or a
   case label.  Labels should only start a new basic block if their
   previous statement wasn't a label.  Otherwise, sequence of labels
   would generate unnecessary basic blocks that only contain a single
   label.  */

static inline bool
stmt_starts_bb_p (gimple *stmt, gimple *prev_stmt)
{
  if (stmt == NULL)
    return false;

  /* PREV_STMT is only set to a debug stmt if the debug stmt is before
     any nondebug stmts in the block.  We don't want to start another
     block in this case: the debug stmt will already have started the
     one STMT would start if we weren't outputting debug stmts.  */
  if (prev_stmt && is_gimple_debug (prev_stmt))
    return false;

  /* Labels start a new basic block only if the preceding statement
     wasn't a label of the same type.  This prevents the creation of
     consecutive blocks that have nothing but a single label.  */
  if (glabel *label_stmt = dyn_cast <glabel *> (stmt))
    {
      /* Nonlocal and computed GOTO targets always start a new block.  */
      if (DECL_NONLOCAL (gimple_label_label (label_stmt))
	  || FORCED_LABEL (gimple_label_label (label_stmt)))
	return true;

      if (glabel *plabel = safe_dyn_cast <glabel *> (prev_stmt))
	{
	  if (DECL_NONLOCAL (gimple_label_label (plabel))
	      || !DECL_ARTIFICIAL (gimple_label_label (plabel)))
	    return true;

	  cfg_stats.num_merged_labels++;
	  return false;
	}
      else
	return true;
    }
  else if (gimple_code (stmt) == GIMPLE_CALL)
    {
      if (gimple_call_flags (stmt) & ECF_RETURNS_TWICE)
	/* setjmp acts similar to a nonlocal GOTO target and thus should
	   start a new block.  */
	return true;
      if (gimple_call_internal_p (stmt, IFN_PHI)
	  && prev_stmt
	  && gimple_code (prev_stmt) != GIMPLE_LABEL
	  && (gimple_code (prev_stmt) != GIMPLE_CALL
	      || ! gimple_call_internal_p (prev_stmt, IFN_PHI)))
	/* PHI nodes start a new block unless preceeded by a label
	   or another PHI.  */
	return true;
    }

  return false;
}


/* Return true if T should end a basic block.  */

bool
stmt_ends_bb_p (gimple *t)
{
  return is_ctrl_stmt (t) || is_ctrl_altering_stmt (t);
}

/* Remove block annotations and other data structures.  */

void
delete_tree_cfg_annotations (struct function *fn)
{
  vec_free (label_to_block_map_for_fn (fn));
}

/* Return the virtual phi in BB.  */

gphi *
get_virtual_phi (basic_block bb)
{
  for (gphi_iterator gsi = gsi_start_phis (bb);
       !gsi_end_p (gsi);
       gsi_next (&gsi))
    {
      gphi *phi = gsi.phi ();

      if (virtual_operand_p (PHI_RESULT (phi)))
	return phi;
    }

  return NULL;
}

/* Return the first statement in basic block BB.  */

gimple *
first_stmt (basic_block bb)
{
  gimple_stmt_iterator i = gsi_start_bb (bb);
  gimple *stmt = NULL;

  while (!gsi_end_p (i) && is_gimple_debug ((stmt = gsi_stmt (i))))
    {
      gsi_next (&i);
      stmt = NULL;
    }
  return stmt;
}

/* Return the first non-label statement in basic block BB.  */

static gimple *
first_non_label_stmt (basic_block bb)
{
  gimple_stmt_iterator i = gsi_start_bb (bb);
  while (!gsi_end_p (i) && gimple_code (gsi_stmt (i)) == GIMPLE_LABEL)
    gsi_next (&i);
  return !gsi_end_p (i) ? gsi_stmt (i) : NULL;
}

/* Return the last statement in basic block BB.  */

gimple *
last_stmt (basic_block bb)
{
  gimple_stmt_iterator i = gsi_last_bb (bb);
  gimple *stmt = NULL;

  while (!gsi_end_p (i) && is_gimple_debug ((stmt = gsi_stmt (i))))
    {
      gsi_prev (&i);
      stmt = NULL;
    }
  return stmt;
}

/* Return the last statement of an otherwise empty block.  Return NULL
   if the block is totally empty, or if it contains more than one
   statement.  */

gimple *
last_and_only_stmt (basic_block bb)
{
  gimple_stmt_iterator i = gsi_last_nondebug_bb (bb);
  gimple *last, *prev;

  if (gsi_end_p (i))
    return NULL;

  last = gsi_stmt (i);
  gsi_prev_nondebug (&i);
  if (gsi_end_p (i))
    return last;

  /* Empty statements should no longer appear in the instruction stream.
     Everything that might have appeared before should be deleted by
     remove_useless_stmts, and the optimizers should just gsi_remove
     instead of smashing with build_empty_stmt.

     Thus the only thing that should appear here in a block containing
     one executable statement is a label.  */
  prev = gsi_stmt (i);
  if (gimple_code (prev) == GIMPLE_LABEL)
    return last;
  else
    return NULL;
}

/* Returns the basic block after which the new basic block created
   by splitting edge EDGE_IN should be placed.  Tries to keep the new block
   near its "logical" location.  This is of most help to humans looking
   at debugging dumps.  */

basic_block
split_edge_bb_loc (edge edge_in)
{
  basic_block dest = edge_in->dest;
  basic_block dest_prev = dest->prev_bb;

  if (dest_prev)
    {
      edge e = find_edge (dest_prev, dest);
      if (e && !(e->flags & EDGE_COMPLEX))
	return edge_in->src;
    }
  return dest_prev;
}

/* Split a (typically critical) edge EDGE_IN.  Return the new block.
   Abort on abnormal edges.  */

static basic_block
gimple_split_edge (edge edge_in)
{
  basic_block new_bb, after_bb, dest;
  edge new_edge, e;

  /* Abnormal edges cannot be split.  */
  gcc_assert (!(edge_in->flags & EDGE_ABNORMAL));

  dest = edge_in->dest;

  after_bb = split_edge_bb_loc (edge_in);

  new_bb = create_empty_bb (after_bb);
  new_bb->count = edge_in->count ();

  /* We want to avoid re-allocating PHIs when we first
     add the fallthru edge from new_bb to dest but we also
     want to avoid changing PHI argument order when
     first redirecting edge_in away from dest.  The former
     avoids changing PHI argument order by adding them
     last and then the redirection swapping it back into
     place by means of unordered remove.
     So hack around things by temporarily removing all PHIs
     from the destination during the edge redirection and then
     making sure the edges stay in order.  */
  gimple_seq saved_phis = phi_nodes (dest);
  unsigned old_dest_idx = edge_in->dest_idx;
  set_phi_nodes (dest, NULL);
  new_edge = make_single_succ_edge (new_bb, dest, EDGE_FALLTHRU);
  e = redirect_edge_and_branch (edge_in, new_bb);
  gcc_assert (e == edge_in && new_edge->dest_idx == old_dest_idx);
  /* set_phi_nodes sets the BB of the PHI nodes, so do it manually here.  */
  dest->il.gimple.phi_nodes = saved_phis;

  return new_bb;
}


/* Verify properties of the address expression T whose base should be
   TREE_ADDRESSABLE if VERIFY_ADDRESSABLE is true.  */

static bool 
verify_address (tree t, bool verify_addressable)
{
  bool old_constant;
  bool old_side_effects;
  bool new_constant;
  bool new_side_effects;

  old_constant = TREE_CONSTANT (t);
  old_side_effects = TREE_SIDE_EFFECTS (t);

  recompute_tree_invariant_for_addr_expr (t);
  new_side_effects = TREE_SIDE_EFFECTS (t);
  new_constant = TREE_CONSTANT (t);

  if (old_constant != new_constant)
    {
      error ("constant not recomputed when %<ADDR_EXPR%> changed");
      return true;
    }
  if (old_side_effects != new_side_effects)
    {
      error ("side effects not recomputed when %<ADDR_EXPR%> changed");
      return true;
    }

  tree base = TREE_OPERAND (t, 0);
  while (handled_component_p (base))
    base = TREE_OPERAND (base, 0);

  if (!(VAR_P (base)
	|| TREE_CODE (base) == PARM_DECL
	|| TREE_CODE (base) == RESULT_DECL))
    return false;

  if (verify_addressable && !TREE_ADDRESSABLE (base))
    {
      error ("address taken but %<TREE_ADDRESSABLE%> bit not set");
      return true;
    }

  return false;
}


/* Verify if EXPR is a valid GIMPLE reference expression.  If
   REQUIRE_LVALUE is true verifies it is an lvalue.  Returns true
   if there is an error, otherwise false.  */

static bool
verify_types_in_gimple_reference (tree expr, bool require_lvalue)
{
  const char *code_name = get_tree_code_name (TREE_CODE (expr));

  if (TREE_CODE (expr) == REALPART_EXPR
      || TREE_CODE (expr) == IMAGPART_EXPR
      || TREE_CODE (expr) == BIT_FIELD_REF)
    {
      tree op = TREE_OPERAND (expr, 0);
      if (!is_gimple_reg_type (TREE_TYPE (expr)))
	{
	  error ("non-scalar %qs", code_name);
	  return true;
	}

      if (TREE_CODE (expr) == BIT_FIELD_REF)
	{
	  tree t1 = TREE_OPERAND (expr, 1);
	  tree t2 = TREE_OPERAND (expr, 2);
	  poly_uint64 size, bitpos;
	  if (!poly_int_tree_p (t1, &size)
	      || !poly_int_tree_p (t2, &bitpos)
	      || !types_compatible_p (bitsizetype, TREE_TYPE (t1))
	      || !types_compatible_p (bitsizetype, TREE_TYPE (t2)))
	    {
	      error ("invalid position or size operand to %qs", code_name);
	      return true;
	    }
	  if (INTEGRAL_TYPE_P (TREE_TYPE (expr))
	      && maybe_ne (TYPE_PRECISION (TREE_TYPE (expr)), size))
	    {
	      error ("integral result type precision does not match "
		     "field size of %qs", code_name);
	      return true;
	    }
	  else if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
		   && TYPE_MODE (TREE_TYPE (expr)) != BLKmode
		   && maybe_ne (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (expr))),
				size))
	    {
	      error ("mode size of non-integral result does not "
		     "match field size of %qs",
		     code_name);
	      return true;
	    }
	  if (INTEGRAL_TYPE_P (TREE_TYPE (op))
	      && !type_has_mode_precision_p (TREE_TYPE (op)))
	    {
	      error ("%qs of non-mode-precision operand", code_name);
	      return true;
	    }
	  if (!AGGREGATE_TYPE_P (TREE_TYPE (op))
	      && maybe_gt (size + bitpos,
			   tree_to_poly_uint64 (TYPE_SIZE (TREE_TYPE (op)))))
	    {
	      error ("position plus size exceeds size of referenced object in "
		     "%qs", code_name);
	      return true;
	    }
	}

      if ((TREE_CODE (expr) == REALPART_EXPR
	   || TREE_CODE (expr) == IMAGPART_EXPR)
	  && !useless_type_conversion_p (TREE_TYPE (expr),
					 TREE_TYPE (TREE_TYPE (op))))
	{
	  error ("type mismatch in %qs reference", code_name);
	  debug_generic_stmt (TREE_TYPE (expr));
	  debug_generic_stmt (TREE_TYPE (TREE_TYPE (op)));
	  return true;
	}
      expr = op;
    }

  while (handled_component_p (expr))
    {
      code_name = get_tree_code_name (TREE_CODE (expr));

      if (TREE_CODE (expr) == REALPART_EXPR
	  || TREE_CODE (expr) == IMAGPART_EXPR
	  || TREE_CODE (expr) == BIT_FIELD_REF)
	{
	  error ("non-top-level %qs", code_name);
	  return true;
	}

      tree op = TREE_OPERAND (expr, 0);

      if (TREE_CODE (expr) == ARRAY_REF
	  || TREE_CODE (expr) == ARRAY_RANGE_REF)
	{
	  if (!is_gimple_val (TREE_OPERAND (expr, 1))
	      || (TREE_OPERAND (expr, 2)
		  && !is_gimple_val (TREE_OPERAND (expr, 2)))
	      || (TREE_OPERAND (expr, 3)
		  && !is_gimple_val (TREE_OPERAND (expr, 3))))
	    {
	      error ("invalid operands to %qs", code_name);
	      debug_generic_stmt (expr);
	      return true;
	    }
	}

      /* Verify if the reference array element types are compatible.  */
      if (TREE_CODE (expr) == ARRAY_REF
	  && !useless_type_conversion_p (TREE_TYPE (expr),
					 TREE_TYPE (TREE_TYPE (op))))
	{
	  error ("type mismatch in %qs", code_name);
	  debug_generic_stmt (TREE_TYPE (expr));
	  debug_generic_stmt (TREE_TYPE (TREE_TYPE (op)));
	  return true;
	}
      if (TREE_CODE (expr) == ARRAY_RANGE_REF
	  && !useless_type_conversion_p (TREE_TYPE (TREE_TYPE (expr)),
					 TREE_TYPE (TREE_TYPE (op))))
	{
	  error ("type mismatch in %qs", code_name);
	  debug_generic_stmt (TREE_TYPE (TREE_TYPE (expr)));
	  debug_generic_stmt (TREE_TYPE (TREE_TYPE (op)));
	  return true;
	}

      if (TREE_CODE (expr) == COMPONENT_REF)
	{
	  if (TREE_OPERAND (expr, 2)
	      && !is_gimple_val (TREE_OPERAND (expr, 2)))
	    {
	      error ("invalid %qs offset operator", code_name);
	      return true;
	    }
	  if (!useless_type_conversion_p (TREE_TYPE (expr),
					  TREE_TYPE (TREE_OPERAND (expr, 1))))
	    {
	      error ("type mismatch in %qs", code_name);
	      debug_generic_stmt (TREE_TYPE (expr));
	      debug_generic_stmt (TREE_TYPE (TREE_OPERAND (expr, 1)));
	      return true;
	    }
	}

      if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
	{
	  /* For VIEW_CONVERT_EXPRs which are allowed here too, we only check
	     that their operand is not an SSA name or an invariant when
	     requiring an lvalue (this usually means there is a SRA or IPA-SRA
	     bug).  Otherwise there is nothing to verify, gross mismatches at
	     most invoke undefined behavior.  */
	  if (require_lvalue
	      && (TREE_CODE (op) == SSA_NAME
		  || is_gimple_min_invariant (op)))
	    {
	      error ("conversion of %qs on the left hand side of %qs",
		     get_tree_code_name (TREE_CODE (op)), code_name);
	      debug_generic_stmt (expr);
	      return true;
	    }
	  else if (TREE_CODE (op) == SSA_NAME
		   && TYPE_SIZE (TREE_TYPE (expr)) != TYPE_SIZE (TREE_TYPE (op)))
	    {
	      error ("conversion of register to a different size in %qs",
		     code_name);
	      debug_generic_stmt (expr);
	      return true;
	    }
	  else if (!handled_component_p (op))
	    return false;
	}

      expr = op;
    }

  code_name = get_tree_code_name (TREE_CODE (expr));

  if (TREE_CODE (expr) == MEM_REF)
    {
      if (!is_gimple_mem_ref_addr (TREE_OPERAND (expr, 0))
	  || (TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR
	      && verify_address (TREE_OPERAND (expr, 0), false)))
	{
	  error ("invalid address operand in %qs", code_name);
	  debug_generic_stmt (expr);
	  return true;
	}
      if (!poly_int_tree_p (TREE_OPERAND (expr, 1))
	  || !POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 1))))
	{
	  error ("invalid offset operand in %qs", code_name);
	  debug_generic_stmt (expr);
	  return true;
	}
      if (MR_DEPENDENCE_CLIQUE (expr) != 0
	  && MR_DEPENDENCE_CLIQUE (expr) > cfun->last_clique)
	{
	  error ("invalid clique in %qs", code_name);
	  debug_generic_stmt (expr);
	  return true;
	}
    }
  else if (TREE_CODE (expr) == TARGET_MEM_REF)
    {
      if (!TMR_BASE (expr)
	  || !is_gimple_mem_ref_addr (TMR_BASE (expr))
	  || (TREE_CODE (TMR_BASE (expr)) == ADDR_EXPR
	      && verify_address (TMR_BASE (expr), false)))
	{
	  error ("invalid address operand in %qs", code_name);
	  return true;
	}
      if (!TMR_OFFSET (expr)
	  || !poly_int_tree_p (TMR_OFFSET (expr))
	  || !POINTER_TYPE_P (TREE_TYPE (TMR_OFFSET (expr))))
	{
	  error ("invalid offset operand in %qs", code_name);
	  debug_generic_stmt (expr);
	  return true;
	}
      if (MR_DEPENDENCE_CLIQUE (expr) != 0
	  && MR_DEPENDENCE_CLIQUE (expr) > cfun->last_clique)
	{
	  error ("invalid clique in %qs", code_name);
	  debug_generic_stmt (expr);
	  return true;
	}
    }
  else if (TREE_CODE (expr) == INDIRECT_REF)
    {
      error ("%qs in gimple IL", code_name);
      debug_generic_stmt (expr);
      return true;
    }

  if (!require_lvalue
      && (TREE_CODE (expr) == SSA_NAME || is_gimple_min_invariant (expr)))
    return false;

  if (TREE_CODE (expr) != SSA_NAME && is_gimple_id (expr))
    return false;

  if (TREE_CODE (expr) != TARGET_MEM_REF
      && TREE_CODE (expr) != MEM_REF)
    {
      error ("invalid expression for min lvalue");
      return true;
    }

  return false;
}

/* Returns true if there is one pointer type in TYPE_POINTER_TO (SRC_OBJ)
   list of pointer-to types that is trivially convertible to DEST.  */

static bool
one_pointer_to_useless_type_conversion_p (tree dest, tree src_obj)
{
  tree src;

  if (!TYPE_POINTER_TO (src_obj))
    return true;

  for (src = TYPE_POINTER_TO (src_obj); src; src = TYPE_NEXT_PTR_TO (src))
    if (useless_type_conversion_p (dest, src))
      return true;

  return false;
}

/* Return true if TYPE1 is a fixed-point type and if conversions to and
   from TYPE2 can be handled by FIXED_CONVERT_EXPR.  */

static bool
valid_fixed_convert_types_p (tree type1, tree type2)
{
  return (FIXED_POINT_TYPE_P (type1)
	  && (INTEGRAL_TYPE_P (type2)
	      || SCALAR_FLOAT_TYPE_P (type2)
	      || FIXED_POINT_TYPE_P (type2)));
}

/* Verify the contents of a GIMPLE_CALL STMT.  Returns true when there
   is a problem, otherwise false.  */

static bool
verify_gimple_call (gcall *stmt)
{
  tree fn = gimple_call_fn (stmt);
  tree fntype, fndecl;
  unsigned i;

  if (gimple_call_internal_p (stmt))
    {
      if (fn)
	{
	  error ("gimple call has two targets");
	  debug_generic_stmt (fn);
	  return true;
	}
    }
  else
    {
      if (!fn)
	{
	  error ("gimple call has no target");
	  return true;
	}
    }

  if (fn && !is_gimple_call_addr (fn))
    {
      error ("invalid function in gimple call");
      debug_generic_stmt (fn);
      return true;
    }

  if (fn
      && (!POINTER_TYPE_P (TREE_TYPE (fn))
	  || (TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) != FUNCTION_TYPE
	      && TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) != METHOD_TYPE)))
    {
      error ("non-function in gimple call");
      return true;
    }

   fndecl = gimple_call_fndecl (stmt);
   if (fndecl
       && TREE_CODE (fndecl) == FUNCTION_DECL
       && DECL_LOOPING_CONST_OR_PURE_P (fndecl)
       && !DECL_PURE_P (fndecl)
       && !TREE_READONLY (fndecl))
     {
       error ("invalid pure const state for function");
       return true;
     }

  tree lhs = gimple_call_lhs (stmt);
  if (lhs
      && (!is_gimple_reg (lhs)
	  && (!is_gimple_lvalue (lhs)
	      || verify_types_in_gimple_reference
		   (TREE_CODE (lhs) == WITH_SIZE_EXPR
		    ? TREE_OPERAND (lhs, 0) : lhs, true))))
    {
      error ("invalid LHS in gimple call");
      return true;
    }

  if (gimple_call_ctrl_altering_p (stmt)
      && gimple_call_noreturn_p (stmt)
      && should_remove_lhs_p (lhs))
    {
      error ("LHS in %<noreturn%> call");
      return true;
    }

  fntype = gimple_call_fntype (stmt);
  if (fntype
      && lhs
      && !useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (fntype))
      /* ???  At least C++ misses conversions at assignments from
	 void * call results.
	 For now simply allow arbitrary pointer type conversions.  */
      && !(POINTER_TYPE_P (TREE_TYPE (lhs))
	   && POINTER_TYPE_P (TREE_TYPE (fntype))))
    {
      error ("invalid conversion in gimple call");
      debug_generic_stmt (TREE_TYPE (lhs));
      debug_generic_stmt (TREE_TYPE (fntype));
      return true;
    }

  if (gimple_call_chain (stmt)
      && !is_gimple_val (gimple_call_chain (stmt)))
    {
      error ("invalid static chain in gimple call");
      debug_generic_stmt (gimple_call_chain (stmt));
      return true;
    }

  /* If there is a static chain argument, the call should either be
     indirect, or the decl should have DECL_STATIC_CHAIN set.  */
  if (gimple_call_chain (stmt)
      && fndecl
      && !DECL_STATIC_CHAIN (fndecl))
    {
      error ("static chain with function that doesn%'t use one");
      return true;
    }

  if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
    {
      switch (DECL_FUNCTION_CODE (fndecl))
	{
	case BUILT_IN_UNREACHABLE:
	case BUILT_IN_TRAP:
	  if (gimple_call_num_args (stmt) > 0)
	    {
	      /* Built-in unreachable with parameters might not be caught by
		 undefined behavior sanitizer.  Front-ends do check users do not
		 call them that way but we also produce calls to
		 __builtin_unreachable internally, for example when IPA figures
		 out a call cannot happen in a legal program.  In such cases,
		 we must make sure arguments are stripped off.  */
	      error ("%<__builtin_unreachable%> or %<__builtin_trap%> call "
		     "with arguments");
	      return true;
	    }
	  break;
	default:
	  break;
	}
    }

  /* For a call to .DEFERRED_INIT,
     LHS = DEFERRED_INIT (SIZE of the DECL, INIT_TYPE, NAME of the DECL)
     we should guarantee that when the 1st argument is a constant, it should
     be the same as the size of the LHS.  */

  if (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
    {
      tree size_of_arg0 = gimple_call_arg (stmt, 0);
      tree size_of_lhs = TYPE_SIZE_UNIT (TREE_TYPE (lhs));

      if (TREE_CODE (lhs) == SSA_NAME)
	lhs = SSA_NAME_VAR (lhs);

      poly_uint64 size_from_arg0, size_from_lhs;
      bool is_constant_size_arg0 = poly_int_tree_p (size_of_arg0,
						    &size_from_arg0);
      bool is_constant_size_lhs = poly_int_tree_p (size_of_lhs,
						   &size_from_lhs);
      if (is_constant_size_arg0 && is_constant_size_lhs)
	if (maybe_ne (size_from_arg0, size_from_lhs))
	  {
	    error ("%<DEFERRED_INIT%> calls should have same "
		   "constant size for the first argument and LHS");
	    return true;
	  }
    }

  /* ???  The C frontend passes unpromoted arguments in case it
     didn't see a function declaration before the call.  So for now
     leave the call arguments mostly unverified.  Once we gimplify
     unit-at-a-time we have a chance to fix this.  */
  for (i = 0; i < gimple_call_num_args (stmt); ++i)
    {
      tree arg = gimple_call_arg (stmt, i);
      if ((is_gimple_reg_type (TREE_TYPE (arg))
	   && !is_gimple_val (arg))
	  || (!is_gimple_reg_type (TREE_TYPE (arg))
	      && !is_gimple_lvalue (arg)))
	{
	  error ("invalid argument to gimple call");
	  debug_generic_expr (arg);
	  return true;
	}
      if (!is_gimple_reg (arg))
	{
	  if (TREE_CODE (arg) == WITH_SIZE_EXPR)
	    arg = TREE_OPERAND (arg, 0);
	  if (verify_types_in_gimple_reference (arg, false))
	    return true;
	}
    }

  return false;
}

/* Verifies the gimple comparison with the result type TYPE and
   the operands OP0 and OP1, comparison code is CODE.  */

static bool
verify_gimple_comparison (tree type, tree op0, tree op1, enum tree_code code)
{
  tree op0_type = TREE_TYPE (op0);
  tree op1_type = TREE_TYPE (op1);

  if (!is_gimple_val (op0) || !is_gimple_val (op1))
    {
      error ("invalid operands in gimple comparison");
      return true;
    }

  /* For comparisons we do not have the operations type as the
     effective type the comparison is carried out in.  Instead
     we require that either the first operand is trivially
     convertible into the second, or the other way around.  */
  if (!useless_type_conversion_p (op0_type, op1_type)
      && !useless_type_conversion_p (op1_type, op0_type))
    {
      error ("mismatching comparison operand types");
      debug_generic_expr (op0_type);
      debug_generic_expr (op1_type);
      return true;
    }

  /* The resulting type of a comparison may be an effective boolean type.  */
  if (INTEGRAL_TYPE_P (type)
      && (TREE_CODE (type) == BOOLEAN_TYPE
	  || TYPE_PRECISION (type) == 1))
    {
      if ((TREE_CODE (op0_type) == VECTOR_TYPE
	   || TREE_CODE (op1_type) == VECTOR_TYPE)
	  && code != EQ_EXPR && code != NE_EXPR
	  && !VECTOR_BOOLEAN_TYPE_P (op0_type)
	  && !VECTOR_INTEGER_TYPE_P (op0_type))
	{
	  error ("unsupported operation or type for vector comparison"
		 " returning a boolean");
	  debug_generic_expr (op0_type);
	  debug_generic_expr (op1_type);
	  return true;
        }
    }
  /* Or a boolean vector type with the same element count
     as the comparison operand types.  */
  else if (TREE_CODE (type) == VECTOR_TYPE
	   && TREE_CODE (TREE_TYPE (type)) == BOOLEAN_TYPE)
    {
      if (TREE_CODE (op0_type) != VECTOR_TYPE
	  || TREE_CODE (op1_type) != VECTOR_TYPE)
        {
          error ("non-vector operands in vector comparison");
          debug_generic_expr (op0_type);
          debug_generic_expr (op1_type);
          return true;
        }

      if (maybe_ne (TYPE_VECTOR_SUBPARTS (type),
		    TYPE_VECTOR_SUBPARTS (op0_type)))
        {
          error ("invalid vector comparison resulting type");
          debug_generic_expr (type);
          return true;
        }
    }
  else
    {
      error ("bogus comparison result type");
      debug_generic_expr (type);
      return true;
    }

  return false;
}

/* Verify a gimple assignment statement STMT with an unary rhs.
   Returns true if anything is wrong.  */

static bool
verify_gimple_assign_unary (gassign *stmt)
{
  enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
  tree lhs = gimple_assign_lhs (stmt);
  tree lhs_type = TREE_TYPE (lhs);
  tree rhs1 = gimple_assign_rhs1 (stmt);
  tree rhs1_type = TREE_TYPE (rhs1);

  if (!is_gimple_reg (lhs))
    {
      error ("non-register as LHS of unary operation");
      return true;
    }

  if (!is_gimple_val (rhs1))
    {
      error ("invalid operand in unary operation");
      return true;
    }

  const char* const code_name = get_tree_code_name (rhs_code);

  /* First handle conversions.  */
  switch (rhs_code)
    {
    CASE_CONVERT:
      {
	/* Allow conversions between vectors with the same number of elements,
	   provided that the conversion is OK for the element types too.  */
	if (VECTOR_TYPE_P (lhs_type)
	    && VECTOR_TYPE_P (rhs1_type)
	    && known_eq (TYPE_VECTOR_SUBPARTS (lhs_type),
			 TYPE_VECTOR_SUBPARTS (rhs1_type)))
	  {
	    lhs_type = TREE_TYPE (lhs_type);
	    rhs1_type = TREE_TYPE (rhs1_type);
	  }
	else if (VECTOR_TYPE_P (lhs_type) || VECTOR_TYPE_P (rhs1_type))
	  {
	    error ("invalid vector types in nop conversion");
	    debug_generic_expr (lhs_type);
	    debug_generic_expr (rhs1_type);
	    return true;
	  }

	/* Allow conversions from pointer type to integral type only if
	   there is no sign or zero extension involved.
	   For targets were the precision of ptrofftype doesn't match that
	   of pointers we allow conversions to types where
	   POINTERS_EXTEND_UNSIGNED specifies how that works.  */
	if ((POINTER_TYPE_P (lhs_type)
	     && INTEGRAL_TYPE_P (rhs1_type))
	    || (POINTER_TYPE_P (rhs1_type)
		&& INTEGRAL_TYPE_P (lhs_type)
		&& (TYPE_PRECISION (rhs1_type) >= TYPE_PRECISION (lhs_type)
#if defined(POINTERS_EXTEND_UNSIGNED)
		    || (TYPE_MODE (rhs1_type) == ptr_mode
			&& (TYPE_PRECISION (lhs_type)
			      == BITS_PER_WORD /* word_mode */
			    || (TYPE_PRECISION (lhs_type)
				  == GET_MODE_PRECISION (Pmode))))
#endif
		   )))
	  return false;

	/* Allow conversion from integral to offset type and vice versa.  */
	if ((TREE_CODE (lhs_type) == OFFSET_TYPE
	     && INTEGRAL_TYPE_P (rhs1_type))
	    || (INTEGRAL_TYPE_P (lhs_type)
		&& TREE_CODE (rhs1_type) == OFFSET_TYPE))
	  return false;

	/* Otherwise assert we are converting between types of the
	   same kind.  */
	if (INTEGRAL_TYPE_P (lhs_type) != INTEGRAL_TYPE_P (rhs1_type))
	  {
	    error ("invalid types in nop conversion");
	    debug_generic_expr (lhs_type);
	    debug_generic_expr (rhs1_type);
	    return true;
	  }

	return false;
      }

    case ADDR_SPACE_CONVERT_EXPR:
      {
	if (!POINTER_TYPE_P (rhs1_type) || !POINTER_TYPE_P (lhs_type)
	    || (TYPE_ADDR_SPACE (TREE_TYPE (rhs1_type))
		== TYPE_ADDR_SPACE (TREE_TYPE (lhs_type))))
	  {
	    error ("invalid types in address space conversion");
	    debug_generic_expr (lhs_type);
	    debug_generic_expr (rhs1_type);
	    return true;
	  }

	return false;
      }

    case FIXED_CONVERT_EXPR:
      {
	if (!valid_fixed_convert_types_p (lhs_type, rhs1_type)
	    && !valid_fixed_convert_types_p (rhs1_type, lhs_type))
	  {
	    error ("invalid types in fixed-point conversion");
	    debug_generic_expr (lhs_type);
	    debug_generic_expr (rhs1_type);
	    return true;
	  }

	return false;
      }

    case FLOAT_EXPR:
      {
	if ((!INTEGRAL_TYPE_P (rhs1_type) || !SCALAR_FLOAT_TYPE_P (lhs_type))
	    && (!VECTOR_INTEGER_TYPE_P (rhs1_type)
	        || !VECTOR_FLOAT_TYPE_P (lhs_type)))
	  {
	    error ("invalid types in conversion to floating-point");
	    debug_generic_expr (lhs_type);
	    debug_generic_expr (rhs1_type);
	    return true;
	  }

        return false;
      }

    case FIX_TRUNC_EXPR:
      {
        if ((!INTEGRAL_TYPE_P (lhs_type) || !SCALAR_FLOAT_TYPE_P (rhs1_type))
            && (!VECTOR_INTEGER_TYPE_P (lhs_type)
                || !VECTOR_FLOAT_TYPE_P (rhs1_type)))
	  {
	    error ("invalid types in conversion to integer");
	    debug_generic_expr (lhs_type);
	    debug_generic_expr (rhs1_type);
	    return true;
	  }

        return false;
      }

    case VEC_UNPACK_HI_EXPR:
    case VEC_UNPACK_LO_EXPR:
    case VEC_UNPACK_FLOAT_HI_EXPR:
    case VEC_UNPACK_FLOAT_LO_EXPR:
    case VEC_UNPACK_FIX_TRUNC_HI_EXPR:
    case VEC_UNPACK_FIX_TRUNC_LO_EXPR:
      if (TREE_CODE (rhs1_type) != VECTOR_TYPE
          || TREE_CODE (lhs_type) != VECTOR_TYPE
          || (!INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))
	      && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (lhs_type)))
          || (!INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))
	      && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (rhs1_type)))
	  || ((rhs_code == VEC_UNPACK_HI_EXPR
	       || rhs_code == VEC_UNPACK_LO_EXPR)
	      && (INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))
		  != INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))))
	  || ((rhs_code == VEC_UNPACK_FLOAT_HI_EXPR
	       || rhs_code == VEC_UNPACK_FLOAT_LO_EXPR)
	      && (INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))
		  || SCALAR_FLOAT_TYPE_P (TREE_TYPE (rhs1_type))))
	  || ((rhs_code == VEC_UNPACK_FIX_TRUNC_HI_EXPR
	       || rhs_code == VEC_UNPACK_FIX_TRUNC_LO_EXPR)
	      && (INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))
		  || SCALAR_FLOAT_TYPE_P (TREE_TYPE (lhs_type))))
	  || (maybe_ne (GET_MODE_SIZE (element_mode (lhs_type)),
			2 * GET_MODE_SIZE (element_mode (rhs1_type)))
	      && (!VECTOR_BOOLEAN_TYPE_P (lhs_type)
		  || !VECTOR_BOOLEAN_TYPE_P (rhs1_type)))
	  || maybe_ne (2 * TYPE_VECTOR_SUBPARTS (lhs_type),
		       TYPE_VECTOR_SUBPARTS (rhs1_type)))
	{
	  error ("type mismatch in %qs expression", code_name);
	  debug_generic_expr (lhs_type);
	  debug_generic_expr (rhs1_type);
	  return true;
        }

      return false;

    case NEGATE_EXPR:
    case ABS_EXPR:
    case BIT_NOT_EXPR:
    case PAREN_EXPR:
    case CONJ_EXPR:
      /* Disallow pointer and offset types for many of the unary gimple. */
      if (POINTER_TYPE_P (lhs_type)
	  || TREE_CODE (lhs_type) == OFFSET_TYPE)
	{
	  error ("invalid types for %qs", code_name);
	  debug_generic_expr (lhs_type);
	  debug_generic_expr (rhs1_type);
	  return true;
	}
      break;

    case ABSU_EXPR:
      if (!ANY_INTEGRAL_TYPE_P (lhs_type)
	  || !TYPE_UNSIGNED (lhs_type)
	  || !ANY_INTEGRAL_TYPE_P (rhs1_type)
	  || TYPE_UNSIGNED (rhs1_type)
	  || element_precision (lhs_type) != element_precision (rhs1_type))
	{
	  error ("invalid types for %qs", code_name);
	  debug_generic_expr (lhs_type);
	  debug_generic_expr (rhs1_type);
	  return true;
	}
      return false;

    case VEC_DUPLICATE_EXPR:
      if (TREE_CODE (lhs_type) != VECTOR_TYPE
	  || !useless_type_conversion_p (TREE_TYPE (lhs_type), rhs1_type))
	{
	  error ("%qs should be from a scalar to a like vector", code_name);
	  debug_generic_expr (lhs_type);
	  debug_generic_expr (rhs1_type);
	  return true;
	}
      return false;

    default:
      gcc_unreachable ();
    }

  /* For the remaining codes assert there is no conversion involved.  */
  if (!useless_type_conversion_p (lhs_type, rhs1_type))
    {
      error ("non-trivial conversion in unary operation");
      debug_generic_expr (lhs_type);
      debug_generic_expr (rhs1_type);
      return true;
    }

  return false;
}

/* Verify a gimple assignment statement STMT with a binary rhs.
   Returns true if anything is wrong.  */

static bool
verify_gimple_assign_binary (gassign *stmt)
{
  enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
  tree lhs = gimple_assign_lhs (stmt);
  tree lhs_type = TREE_TYPE (lhs);
  tree rhs1 = gimple_assign_rhs1 (stmt);
  tree rhs1_type = TREE_TYPE (rhs1);
  tree rhs2 = gimple_assign_rhs2 (stmt);
  tree rhs2_type = TREE_TYPE (rhs2);

  if (!is_gimple_reg (lhs))
    {
      error ("non-register as LHS of binary operation");
      return true;
    }

  if (!is_gimple_val (rhs1)
      || !is_gimple_val (rhs2))
    {
      error ("invalid operands in binary operation");
      return true;
    }

  const char* const code_name = get_tree_code_name (rhs_code);

  /* First handle operations that involve different types.  */
  switch (rhs_code)
    {
    case COMPLEX_EXPR:
      {
	if (TREE_CODE (lhs_type) != COMPLEX_TYPE
	    || !(INTEGRAL_TYPE_P (rhs1_type)
	         || SCALAR_FLOAT_TYPE_P (rhs1_type))
	    || !(INTEGRAL_TYPE_P (rhs2_type)
	         || SCALAR_FLOAT_TYPE_P (rhs2_type)))
	  {
	    error ("type mismatch in %qs", code_name);
	    debug_generic_expr (lhs_type);
	    debug_generic_expr (rhs1_type);
	    debug_generic_expr (rhs2_type);
	    return true;
	  }

	return false;
      }

    case LSHIFT_EXPR:
    case RSHIFT_EXPR:
    case LROTATE_EXPR:
    case RROTATE_EXPR:
      {
	/* Shifts and rotates are ok on integral types, fixed point
	   types and integer vector types.  */
	if ((!INTEGRAL_TYPE_P (rhs1_type)
	     && !FIXED_POINT_TYPE_P (rhs1_type)
	     && !(TREE_CODE (rhs1_type) == VECTOR_TYPE
		  && INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))))
	    || (!INTEGRAL_TYPE_P (rhs2_type)
		/* Vector shifts of vectors are also ok.  */
		&& !(TREE_CODE (rhs1_type) == VECTOR_TYPE
		     && INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))
		     && TREE_CODE (rhs2_type) == VECTOR_TYPE
		     && INTEGRAL_TYPE_P (TREE_TYPE (rhs2_type))))
	    || !useless_type_conversion_p (lhs_type, rhs1_type))
	  {
	    error ("type mismatch in %qs", code_name);
	    debug_generic_expr (lhs_type);
	    debug_generic_expr (rhs1_type);
	    debug_generic_expr (rhs2_type);
	    return true;
	  }

	return false;
      }

    case WIDEN_LSHIFT_EXPR:
      {
        if (!INTEGRAL_TYPE_P (lhs_type)
            || !INTEGRAL_TYPE_P (rhs1_type)
            || TREE_CODE (rhs2) != INTEGER_CST
            || (2 * TYPE_PRECISION (rhs1_type) > TYPE_PRECISION (lhs_type)))
          {
	    error ("type mismatch in %qs", code_name);
            debug_generic_expr (lhs_type);
            debug_generic_expr (rhs1_type);
            debug_generic_expr (rhs2_type);
            return true;
          }

        return false;
      }

    case VEC_WIDEN_LSHIFT_HI_EXPR:
    case VEC_WIDEN_LSHIFT_LO_EXPR:
      {
        if (TREE_CODE (rhs1_type) != VECTOR_TYPE
            || TREE_CODE (lhs_type) != VECTOR_TYPE
            || !INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))
            || !INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))
            || TREE_CODE (rhs2) != INTEGER_CST
            || (2 * TYPE_PRECISION (TREE_TYPE (rhs1_type))
                > TYPE_PRECISION (TREE_TYPE (lhs_type))))
          {
	    error ("type mismatch in %qs", code_name);
            debug_generic_expr (lhs_type);
            debug_generic_expr (rhs1_type);
            debug_generic_expr (rhs2_type);
            return true;
          }

        return false;
      }

    case WIDEN_PLUS_EXPR:
    case WIDEN_MINUS_EXPR:
    case PLUS_EXPR:
    case MINUS_EXPR:
      {
	tree lhs_etype = lhs_type;
	tree rhs1_etype = rhs1_type;
	tree rhs2_etype = rhs2_type;
	if (TREE_CODE (lhs_type) == VECTOR_TYPE)
	  {
	    if (TREE_CODE (rhs1_type) != VECTOR_TYPE
		|| TREE_CODE (rhs2_type) != VECTOR_TYPE)
	      {
		error ("invalid non-vector operands to %qs", code_name);
		return true;
	      }
	    lhs_etype = TREE_TYPE (lhs_type);
	    rhs1_etype = TREE_TYPE (rhs1_type);
	    rhs2_etype = TREE_TYPE (rhs2_type);
	  }
	if (POINTER_TYPE_P (lhs_etype)
	    || POINTER_TYPE_P (rhs1_etype)
	    || POINTER_TYPE_P (rhs2_etype))
	  {
	    error ("invalid (pointer) operands %qs", code_name);
	    return true;
	  }

	/* Continue with generic binary expression handling.  */
	break;
      }

    case POINTER_PLUS_EXPR:
      {
	if (!POINTER_TYPE_P (rhs1_type)
	    || !useless_type_conversion_p (lhs_type, rhs1_type)
	    || !ptrofftype_p (rhs2_type))
	  {
	    error ("type mismatch in %qs", code_name);
	    debug_generic_stmt (lhs_type);
	    debug_generic_stmt (rhs1_type);
	    debug_generic_stmt (rhs2_type);
	    return true;
	  }

	return false;
      }

    case POINTER_DIFF_EXPR:
      {
	if (!POINTER_TYPE_P (rhs1_type)
	    || !POINTER_TYPE_P (rhs2_type)
	    /* Because we special-case pointers to void we allow difference
	       of arbitrary pointers with the same mode.  */
	    || TYPE_MODE (rhs1_type) != TYPE_MODE (rhs2_type)
	    || !INTEGRAL_TYPE_P (lhs_type)
	    || TYPE_UNSIGNED (lhs_type)
	    || TYPE_PRECISION (lhs_type) != TYPE_PRECISION (rhs1_type))
	  {
	    error ("type mismatch in %qs", code_name);
	    debug_generic_stmt (lhs_type);
	    debug_generic_stmt (rhs1_type);
	    debug_generic_stmt (rhs2_type);
	    return true;
	  }

	return false;
      }

    case TRUTH_ANDIF_EXPR:
    case TRUTH_ORIF_EXPR:
    case TRUTH_AND_EXPR:
    case TRUTH_OR_EXPR:
    case TRUTH_XOR_EXPR:

      gcc_unreachable ();

    case LT_EXPR:
    case LE_EXPR:
    case GT_EXPR:
    case GE_EXPR:
    case EQ_EXPR:
    case NE_EXPR:
    case UNORDERED_EXPR:
    case ORDERED_EXPR:
    case UNLT_EXPR:
    case UNLE_EXPR:
    case UNGT_EXPR:
    case UNGE_EXPR:
    case UNEQ_EXPR:
    case LTGT_EXPR:
      /* Comparisons are also binary, but the result type is not
	 connected to the operand types.  */
      return verify_gimple_comparison (lhs_type, rhs1, rhs2, rhs_code);

    case WIDEN_MULT_EXPR:
      if (TREE_CODE (lhs_type) != INTEGER_TYPE)
	return true;
      return ((2 * TYPE_PRECISION (rhs1_type) > TYPE_PRECISION (lhs_type))
	      || (TYPE_PRECISION (rhs1_type) != TYPE_PRECISION (rhs2_type)));

    case WIDEN_SUM_EXPR:
      {
        if (((TREE_CODE (rhs1_type) != VECTOR_TYPE
	      || TREE_CODE (lhs_type) != VECTOR_TYPE)
	     && ((!INTEGRAL_TYPE_P (rhs1_type)
		  && !SCALAR_FLOAT_TYPE_P (rhs1_type))
		 || (!INTEGRAL_TYPE_P (lhs_type)
		     && !SCALAR_FLOAT_TYPE_P (lhs_type))))
	    || !useless_type_conversion_p (lhs_type, rhs2_type)
	    || maybe_lt (GET_MODE_SIZE (element_mode (rhs2_type)),
			 2 * GET_MODE_SIZE (element_mode (rhs1_type))))
          {
	    error ("type mismatch in %qs", code_name);
            debug_generic_expr (lhs_type);
            debug_generic_expr (rhs1_type);
            debug_generic_expr (rhs2_type);
            return true;
          }
        return false;
      }

    case VEC_WIDEN_MINUS_HI_EXPR:
    case VEC_WIDEN_MINUS_LO_EXPR:
    case VEC_WIDEN_PLUS_HI_EXPR:
    case VEC_WIDEN_PLUS_LO_EXPR:
    case VEC_WIDEN_MULT_HI_EXPR:
    case VEC_WIDEN_MULT_LO_EXPR:
    case VEC_WIDEN_MULT_EVEN_EXPR:
    case VEC_WIDEN_MULT_ODD_EXPR:
      {
        if (TREE_CODE (rhs1_type) != VECTOR_TYPE
            || TREE_CODE (lhs_type) != VECTOR_TYPE
	    || !types_compatible_p (rhs1_type, rhs2_type)
	    || maybe_ne (GET_MODE_SIZE (element_mode (lhs_type)),
			 2 * GET_MODE_SIZE (element_mode (rhs1_type))))
          {
	    error ("type mismatch in %qs", code_name);
            debug_generic_expr (lhs_type);
            debug_generic_expr (rhs1_type);
            debug_generic_expr (rhs2_type);
            return true;
          }
        return false;
      }

    case VEC_PACK_TRUNC_EXPR:
      /* ???  We currently use VEC_PACK_TRUNC_EXPR to simply concat
	 vector boolean types.  */
      if (VECTOR_BOOLEAN_TYPE_P (lhs_type)
	  && VECTOR_BOOLEAN_TYPE_P (rhs1_type)
	  && types_compatible_p (rhs1_type, rhs2_type)
	  && known_eq (TYPE_VECTOR_SUBPARTS (lhs_type),
		       2 * TYPE_VECTOR_SUBPARTS (rhs1_type)))
	return false;

      /* Fallthru.  */
    case VEC_PACK_SAT_EXPR:
    case VEC_PACK_FIX_TRUNC_EXPR:
      {
        if (TREE_CODE (rhs1_type) != VECTOR_TYPE
            || TREE_CODE (lhs_type) != VECTOR_TYPE
            || !((rhs_code == VEC_PACK_FIX_TRUNC_EXPR
		  && SCALAR_FLOAT_TYPE_P (TREE_TYPE (rhs1_type))
		  && INTEGRAL_TYPE_P (TREE_TYPE (lhs_type)))
		 || (INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))
		     == INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))))
	    || !types_compatible_p (rhs1_type, rhs2_type)
	    || maybe_ne (GET_MODE_SIZE (element_mode (rhs1_type)),
			 2 * GET_MODE_SIZE (element_mode (lhs_type)))
	    || maybe_ne (2 * TYPE_VECTOR_SUBPARTS (rhs1_type),
			 TYPE_VECTOR_SUBPARTS (lhs_type)))
          {
	    error ("type mismatch in %qs", code_name);
            debug_generic_expr (lhs_type);
            debug_generic_expr (rhs1_type);
            debug_generic_expr (rhs2_type);
            return true;
          }

        return false;
      }

    case VEC_PACK_FLOAT_EXPR:
      if (TREE_CODE (rhs1_type) != VECTOR_TYPE
	  || TREE_CODE (lhs_type) != VECTOR_TYPE
	  || !INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))
	  || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (lhs_type))
	  || !types_compatible_p (rhs1_type, rhs2_type)
	  || maybe_ne (GET_MODE_SIZE (element_mode (rhs1_type)),
		       2 * GET_MODE_SIZE (element_mode (lhs_type)))
	  || maybe_ne (2 * TYPE_VECTOR_SUBPARTS (rhs1_type),
		       TYPE_VECTOR_SUBPARTS (lhs_type)))
	{
	  error ("type mismatch in %qs", code_name);
	  debug_generic_expr (lhs_type);
	  debug_generic_expr (rhs1_type);
	  debug_generic_expr (rhs2_type);
	  return true;
	}

      return false;

    case MULT_EXPR:
    case MULT_HIGHPART_EXPR:
    case TRUNC_DIV_EXPR:
    case CEIL_DIV_EXPR:
    case FLOOR_DIV_EXPR:
    case ROUND_DIV_EXPR:
    case TRUNC_MOD_EXPR:
    case CEIL_MOD_EXPR:
    case FLOOR_MOD_EXPR:
    case ROUND_MOD_EXPR:
    case RDIV_EXPR:
    case EXACT_DIV_EXPR:
    case BIT_IOR_EXPR:
    case BIT_XOR_EXPR:
      /* Disallow pointer and offset types for many of the binary gimple. */
      if (POINTER_TYPE_P (lhs_type)
	  || TREE_CODE (lhs_type) == OFFSET_TYPE)
	{
	  error ("invalid types for %qs", code_name);
	  debug_generic_expr (lhs_type);
	  debug_generic_expr (rhs1_type);
	  debug_generic_expr (rhs2_type);
	  return true;
	}
      /* Continue with generic binary expression handling.  */
      break;

    case MIN_EXPR:
    case MAX_EXPR:
      /* Continue with generic binary expression handling.  */
      break;

    case BIT_AND_EXPR:
      if (POINTER_TYPE_P (lhs_type)
	  && TREE_CODE (rhs2) == INTEGER_CST)
	break;
      /* Disallow pointer and offset types for many of the binary gimple. */
      if (POINTER_TYPE_P (lhs_type)
	  || TREE_CODE (lhs_type) == OFFSET_TYPE)
	{
	  error ("invalid types for %qs", code_name);
	  debug_generic_expr (lhs_type);
	  debug_generic_expr (rhs1_type);
	  debug_generic_expr (rhs2_type);
	  return true;
	}
      /* Continue with generic binary expression handling.  */
      break;

    case VEC_SERIES_EXPR:
      if (!useless_type_conversion_p (rhs1_type, rhs2_type))
	{
	  error ("type mismatch in %qs", code_name);
	  debug_generic_expr (rhs1_type);
	  debug_generic_expr (rhs2_type);
	  return true;
	}
      if (TREE_CODE (lhs_type) != VECTOR_TYPE
	  || !useless_type_conversion_p (TREE_TYPE (lhs_type), rhs1_type))
	{
	  error ("vector type expected in %qs", code_name);
	  debug_generic_expr (lhs_type);
	  return true;
	}
      return false;

    default:
      gcc_unreachable ();
    }

  if (!useless_type_conversion_p (lhs_type, rhs1_type)
      || !useless_type_conversion_p (lhs_type, rhs2_type))
    {
      error ("type mismatch in binary expression");
      debug_generic_stmt (lhs_type);
      debug_generic_stmt (rhs1_type);
      debug_generic_stmt (rhs2_type);
      return true;
    }

  return false;
}

/* Verify a gimple assignment statement STMT with a ternary rhs.
   Returns true if anything is wrong.  */

static bool
verify_gimple_assign_ternary (gassign *stmt)
{
  enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
  tree lhs = gimple_assign_lhs (stmt);
  tree lhs_type = TREE_TYPE (lhs);
  tree rhs1 = gimple_assign_rhs1 (stmt);
  tree rhs1_type = TREE_TYPE (rhs1);
  tree rhs2 = gimple_assign_rhs2 (stmt);
  tree rhs2_type = TREE_TYPE (rhs2);
  tree rhs3 = gimple_assign_rhs3 (stmt);
  tree rhs3_type = TREE_TYPE (rhs3);

  if (!is_gimple_reg (lhs))
    {
      error ("non-register as LHS of ternary operation");
      return true;
    }

  if (!is_gimple_val (rhs1)
      || !is_gimple_val (rhs2)
      || !is_gimple_val (rhs3))
    {
      error ("invalid operands in ternary operation");
      return true;
    }

  const char* const code_name = get_tree_code_name (rhs_code);

  /* First handle operations that involve different types.  */
  switch (rhs_code)
    {
    case WIDEN_MULT_PLUS_EXPR:
    case WIDEN_MULT_MINUS_EXPR:
      if ((!INTEGRAL_TYPE_P (rhs1_type)
	   && !FIXED_POINT_TYPE_P (rhs1_type))
	  || !useless_type_conversion_p (rhs1_type, rhs2_type)
	  || !useless_type_conversion_p (lhs_type, rhs3_type)
	  || 2 * TYPE_PRECISION (rhs1_type) > TYPE_PRECISION (lhs_type)
	  || TYPE_PRECISION (rhs1_type) != TYPE_PRECISION (rhs2_type))
	{
	  error ("type mismatch in %qs", code_name);
	  debug_generic_expr (lhs_type);
	  debug_generic_expr (rhs1_type);
	  debug_generic_expr (rhs2_type);
	  debug_generic_expr (rhs3_type);
	  return true;
	}
      break;

    case VEC_COND_EXPR:
      if (!VECTOR_BOOLEAN_TYPE_P (rhs1_type)
	  || maybe_ne (TYPE_VECTOR_SUBPARTS (rhs1_type),
		       TYPE_VECTOR_SUBPARTS (lhs_type)))
	{
	  error ("the first argument of a %qs must be of a "
		 "boolean vector type of the same number of elements "
		 "as the result", code_name);
	  debug_generic_expr (lhs_type);
	  debug_generic_expr (rhs1_type);
	  return true;
	}
      /* Fallthrough.  */
    case COND_EXPR:
      if (!useless_type_conversion_p (lhs_type, rhs2_type)
	  || !useless_type_conversion_p (lhs_type, rhs3_type))
	{
	  error ("type mismatch in %qs", code_name);
	  debug_generic_expr (lhs_type);
	  debug_generic_expr (rhs2_type);
	  debug_generic_expr (rhs3_type);
	  return true;
	}
      break;

    case VEC_PERM_EXPR:
      /* If permute is constant, then we allow for lhs and rhs
	 to have different vector types, provided:
	 (1) lhs, rhs1, rhs2 have same element type.
	 (2) rhs3 vector is constant and has integer element type.
	 (3) len(lhs) == len(rhs3) && len(rhs1) == len(rhs2).  */

      if (TREE_CODE (lhs_type) != VECTOR_TYPE
	  || TREE_CODE (rhs1_type) != VECTOR_TYPE
	  || TREE_CODE (rhs2_type) != VECTOR_TYPE
	  || TREE_CODE (rhs3_type) != VECTOR_TYPE)
	{
	  error ("vector types expected in %qs", code_name);
	  debug_generic_expr (lhs_type);
	  debug_generic_expr (rhs1_type);
	  debug_generic_expr (rhs2_type);
	  debug_generic_expr (rhs3_type);
	  return true;
	}

      /* If rhs3 is constant, we allow lhs, rhs1 and rhs2 to be different vector types,
	 as long as lhs, rhs1 and rhs2 have same element type.  */
      if (TREE_CONSTANT (rhs3)
	  ? (!useless_type_conversion_p (TREE_TYPE (lhs_type), TREE_TYPE (rhs1_type))
	     || !useless_type_conversion_p (TREE_TYPE (lhs_type), TREE_TYPE (rhs2_type)))
	  : (!useless_type_conversion_p (lhs_type, rhs1_type)
	     || !useless_type_conversion_p (lhs_type, rhs2_type)))
	{
	    error ("type mismatch in %qs", code_name);
	    debug_generic_expr (lhs_type);
	    debug_generic_expr (rhs1_type);
	    debug_generic_expr (rhs2_type);
	    debug_generic_expr (rhs3_type);
	    return true;
	}

      /* If rhs3 is constant, relax the check len(rhs2) == len(rhs3).  */
      if (maybe_ne (TYPE_VECTOR_SUBPARTS (rhs1_type),
		    TYPE_VECTOR_SUBPARTS (rhs2_type))
	  || (!TREE_CONSTANT(rhs3)
	      && maybe_ne (TYPE_VECTOR_SUBPARTS (rhs2_type),
			   TYPE_VECTOR_SUBPARTS (rhs3_type)))
	  || maybe_ne (TYPE_VECTOR_SUBPARTS (rhs3_type),
		       TYPE_VECTOR_SUBPARTS (lhs_type)))
	{
	  error ("vectors with different element number found in %qs",
		 code_name);
	  debug_generic_expr (lhs_type);
	  debug_generic_expr (rhs1_type);
	  debug_generic_expr (rhs2_type);
	  debug_generic_expr (rhs3_type);
	  return true;
	}

      if (TREE_CODE (TREE_TYPE (rhs3_type)) != INTEGER_TYPE
	  || (TREE_CODE (rhs3) != VECTOR_CST
	      && (GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE
				    (TREE_TYPE (rhs3_type)))
		  != GET_MODE_BITSIZE (SCALAR_TYPE_MODE
				       (TREE_TYPE (rhs1_type))))))
	{
	  error ("invalid mask type in %qs", code_name);
	  debug_generic_expr (lhs_type);
	  debug_generic_expr (rhs1_type);
	  debug_generic_expr (rhs2_type);
	  debug_generic_expr (rhs3_type);
	  return true;
	}

      return false;

    case SAD_EXPR:
      if (!useless_type_conversion_p (rhs1_type, rhs2_type)
	  || !useless_type_conversion_p (lhs_type, rhs3_type)
	  || 2 * GET_MODE_UNIT_BITSIZE (TYPE_MODE (TREE_TYPE (rhs1_type)))
	       > GET_MODE_UNIT_BITSIZE (TYPE_MODE (TREE_TYPE (lhs_type))))
	{
	  error ("type mismatch in %qs", code_name);
	  debug_generic_expr (lhs_type);
	  debug_generic_expr (rhs1_type);
	  debug_generic_expr (rhs2_type);
	  debug_generic_expr (rhs3_type);
	  return true;
	}

      if (TREE_CODE (rhs1_type) != VECTOR_TYPE
	  || TREE_CODE (rhs2_type) != VECTOR_TYPE
	  || TREE_CODE (rhs3_type) != VECTOR_TYPE)
	{
	  error ("vector types expected in %qs", code_name);
	  debug_generic_expr (lhs_type);
	  debug_generic_expr (rhs1_type);
	  debug_generic_expr (rhs2_type);
	  debug_generic_expr (rhs3_type);
	  return true;
	}

      return false;

    case BIT_INSERT_EXPR:
      if (! useless_type_conversion_p (lhs_type, rhs1_type))
	{
	  error ("type mismatch in %qs", code_name);
	  debug_generic_expr (lhs_type);
	  debug_generic_expr (rhs1_type);
	  return true;
	}
      if (! ((INTEGRAL_TYPE_P (rhs1_type)
	      && INTEGRAL_TYPE_P (rhs2_type))
	     /* Vector element insert.  */
	     || (VECTOR_TYPE_P (rhs1_type)
		 && types_compatible_p (TREE_TYPE (rhs1_type), rhs2_type))
	     /* Aligned sub-vector insert.  */
	     || (VECTOR_TYPE_P (rhs1_type)
		 && VECTOR_TYPE_P (rhs2_type)
		 && types_compatible_p (TREE_TYPE (rhs1_type),
					TREE_TYPE (rhs2_type))
		 && multiple_p (TYPE_VECTOR_SUBPARTS (rhs1_type),
				TYPE_VECTOR_SUBPARTS (rhs2_type))
		 && multiple_p (wi::to_poly_offset (rhs3),
				wi::to_poly_offset (TYPE_SIZE (rhs2_type))))))
	{
	  error ("not allowed type combination in %qs", code_name);
	  debug_generic_expr (rhs1_type);
	  debug_generic_expr (rhs2_type);
	  return true;
	}
      if (! tree_fits_uhwi_p (rhs3)
	  || ! types_compatible_p (bitsizetype, TREE_TYPE (rhs3))
	  || ! tree_fits_uhwi_p (TYPE_SIZE (rhs2_type)))
	{
	  error ("invalid position or size in %qs", code_name);
	  return true;
	}
      if (INTEGRAL_TYPE_P (rhs1_type)
	  && !type_has_mode_precision_p (rhs1_type))
	{
	  error ("%qs into non-mode-precision operand", code_name);
	  return true;
	}
      if (INTEGRAL_TYPE_P (rhs1_type))
	{
	  unsigned HOST_WIDE_INT bitpos = tree_to_uhwi (rhs3);
	  if (bitpos >= TYPE_PRECISION (rhs1_type)
	      || (bitpos + TYPE_PRECISION (rhs2_type)
		  > TYPE_PRECISION (rhs1_type)))
	    {
	      error ("insertion out of range in %qs", code_name);
	      return true;
	    }
	}
      else if (VECTOR_TYPE_P (rhs1_type))
	{
	  unsigned HOST_WIDE_INT bitpos = tree_to_uhwi (rhs3);
	  unsigned HOST_WIDE_INT bitsize = tree_to_uhwi (TYPE_SIZE (rhs2_type));
	  if (bitpos % bitsize != 0)
	    {
	      error ("%qs not at element boundary", code_name);
	      return true;
	    }
	}
      return false;

    case DOT_PROD_EXPR:
      {
        if (((TREE_CODE (rhs1_type) != VECTOR_TYPE
	      || TREE_CODE (lhs_type) != VECTOR_TYPE)
	     && ((!INTEGRAL_TYPE_P (rhs1_type)
		  && !SCALAR_FLOAT_TYPE_P (rhs1_type))
		 || (!INTEGRAL_TYPE_P (lhs_type)
		     && !SCALAR_FLOAT_TYPE_P (lhs_type))))
	    /* rhs1_type and rhs2_type may differ in sign.  */
	    || !tree_nop_conversion_p (rhs1_type, rhs2_type)
	    || !useless_type_conversion_p (lhs_type, rhs3_type)
	    || maybe_lt (GET_MODE_SIZE (element_mode (rhs3_type)),
			 2 * GET_MODE_SIZE (element_mode (rhs1_type))))
          {
	    error ("type mismatch in %qs", code_name);
            debug_generic_expr (lhs_type);
            debug_generic_expr (rhs1_type);
            debug_generic_expr (rhs2_type);
            return true;
          }
        return false;
      }

    case REALIGN_LOAD_EXPR:
      /* FIXME.  */
      return false;

    default:
      gcc_unreachable ();
    }
  return false;
}

/* Verify a gimple assignment statement STMT with a single rhs.
   Returns true if anything is wrong.  */

static bool
verify_gimple_assign_single (gassign *stmt)
{
  enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
  tree lhs = gimple_assign_lhs (stmt);
  tree lhs_type = TREE_TYPE (lhs);
  tree rhs1 = gimple_assign_rhs1 (stmt);
  tree rhs1_type = TREE_TYPE (rhs1);
  bool res = false;

  const char* const code_name = get_tree_code_name (rhs_code);

  if (!useless_type_conversion_p (lhs_type, rhs1_type))
    {
      error ("non-trivial conversion in %qs", code_name);
      debug_generic_expr (lhs_type);
      debug_generic_expr (rhs1_type);
      return true;
    }

  if (gimple_clobber_p (stmt)
      && !(DECL_P (lhs) || TREE_CODE (lhs) == MEM_REF))
    {
      error ("%qs LHS in clobber statement",
	     get_tree_code_name (TREE_CODE (lhs)));
      debug_generic_expr (lhs);
      return true;
    }

  if (TREE_CODE (lhs) == WITH_SIZE_EXPR)
    {
      error ("%qs LHS in assignment statement",
	     get_tree_code_name (TREE_CODE (lhs)));
      debug_generic_expr (lhs);
      return true;
    }

  if (handled_component_p (lhs)
      || TREE_CODE (lhs) == MEM_REF
      || TREE_CODE (lhs) == TARGET_MEM_REF)
    res |= verify_types_in_gimple_reference (lhs, true);

  /* Special codes we cannot handle via their class.  */
  switch (rhs_code)
    {
    case ADDR_EXPR:
      {
	tree op = TREE_OPERAND (rhs1, 0);
	if (!is_gimple_addressable (op))
	  {
	    error ("invalid operand in %qs", code_name);
	    return true;
	  }

	/* Technically there is no longer a need for matching types, but
	   gimple hygiene asks for this check.  In LTO we can end up
	   combining incompatible units and thus end up with addresses
	   of globals that change their type to a common one.  */
	if (!in_lto_p
	    && !types_compatible_p (TREE_TYPE (op),
				    TREE_TYPE (TREE_TYPE (rhs1)))
	    && !one_pointer_to_useless_type_conversion_p (TREE_TYPE (rhs1),
							  TREE_TYPE (op)))
	  {
	    error ("type mismatch in %qs", code_name);
	    debug_generic_stmt (TREE_TYPE (rhs1));
	    debug_generic_stmt (TREE_TYPE (op));
	    return true;
	  }

	return (verify_address (rhs1, true)
		|| verify_types_in_gimple_reference (op, true));
      }

    /* tcc_reference  */
    case INDIRECT_REF:
      error ("%qs in gimple IL", code_name);
      return true;

    case COMPONENT_REF:
    case BIT_FIELD_REF:
    case ARRAY_REF:
    case ARRAY_RANGE_REF:
    case VIEW_CONVERT_EXPR:
    case REALPART_EXPR:
    case IMAGPART_EXPR:
    case TARGET_MEM_REF:
    case MEM_REF:
      if (!is_gimple_reg (lhs)
	  && is_gimple_reg_type (TREE_TYPE (lhs)))
	{
	  error ("invalid RHS for gimple memory store: %qs", code_name);
	  debug_generic_stmt (lhs);
	  debug_generic_stmt (rhs1);
	  return true;
	}
      return res || verify_types_in_gimple_reference (rhs1, false);

    /* tcc_constant  */
    case SSA_NAME:
    case INTEGER_CST:
    case REAL_CST:
    case FIXED_CST:
    case COMPLEX_CST:
    case VECTOR_CST:
    case STRING_CST:
      return res;

    /* tcc_declaration  */
    case CONST_DECL:
      return res;
    case VAR_DECL:
    case PARM_DECL:
      if (!is_gimple_reg (lhs)
	  && !is_gimple_reg (rhs1)
	  && is_gimple_reg_type (TREE_TYPE (lhs)))
	{
	  error ("invalid RHS for gimple memory store: %qs", code_name);
	  debug_generic_stmt (lhs);
	  debug_generic_stmt (rhs1);
	  return true;
	}
      return res;

    case CONSTRUCTOR:
      if (TREE_CODE (rhs1_type) == VECTOR_TYPE)
	{
	  unsigned int i;
	  tree elt_i, elt_v, elt_t = NULL_TREE;

	  if (CONSTRUCTOR_NELTS (rhs1) == 0)
	    return res;
	  /* For vector CONSTRUCTORs we require that either it is empty
	     CONSTRUCTOR, or it is a CONSTRUCTOR of smaller vector elements
	     (then the element count must be correct to cover the whole
	     outer vector and index must be NULL on all elements, or it is
	     a CONSTRUCTOR of scalar elements, where we as an exception allow
	     smaller number of elements (assuming zero filling) and
	     consecutive indexes as compared to NULL indexes (such
	     CONSTRUCTORs can appear in the IL from FEs).  */
	  FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (rhs1), i, elt_i, elt_v)
	    {
	      if (elt_t == NULL_TREE)
		{
		  elt_t = TREE_TYPE (elt_v);
		  if (TREE_CODE (elt_t) == VECTOR_TYPE)
		    {
		      tree elt_t = TREE_TYPE (elt_v);
		      if (!useless_type_conversion_p (TREE_TYPE (rhs1_type),
						      TREE_TYPE (elt_t)))
			{
			  error ("incorrect type of vector %qs elements",
				 code_name);
			  debug_generic_stmt (rhs1);
			  return true;
			}
		      else if (maybe_ne (CONSTRUCTOR_NELTS (rhs1)
					 * TYPE_VECTOR_SUBPARTS (elt_t),
					 TYPE_VECTOR_SUBPARTS (rhs1_type)))
			{
			  error ("incorrect number of vector %qs elements",
				 code_name);
			  debug_generic_stmt (rhs1);
			  return true;
			}
		    }
		  else if (!useless_type_conversion_p (TREE_TYPE (rhs1_type),
						       elt_t))
		    {
		      error ("incorrect type of vector %qs elements",
			     code_name);
		      debug_generic_stmt (rhs1);
		      return true;
		    }
		  else if (maybe_gt (CONSTRUCTOR_NELTS (rhs1),
				     TYPE_VECTOR_SUBPARTS (rhs1_type)))
		    {
		      error ("incorrect number of vector %qs elements",
			     code_name);
		      debug_generic_stmt (rhs1);
		      return true;
		    }
		}
	      else if (!useless_type_conversion_p (elt_t, TREE_TYPE (elt_v)))
		{
		  error ("incorrect type of vector CONSTRUCTOR elements");
		  debug_generic_stmt (rhs1);
		  return true;
		}
	      if (elt_i != NULL_TREE
		  && (TREE_CODE (elt_t) == VECTOR_TYPE
		      || TREE_CODE (elt_i) != INTEGER_CST
		      || compare_tree_int (elt_i, i) != 0))
		{
		  error ("vector %qs with non-NULL element index",
			 code_name);
		  debug_generic_stmt (rhs1);
		  return true;
		}
	      if (!is_gimple_val (elt_v))
		{
		  error ("vector %qs element is not a GIMPLE value",
			 code_name);
		  debug_generic_stmt (rhs1);
		  return true;
		}
	    }
	}
      else if (CONSTRUCTOR_NELTS (rhs1) != 0)
	{
	  error ("non-vector %qs with elements", code_name);
	  debug_generic_stmt (rhs1);
	  return true;
	}
      return res;

    case ASSERT_EXPR:
      /* FIXME.  */
      rhs1 = fold (ASSERT_EXPR_COND (rhs1));
      if (rhs1 == boolean_false_node)
	{
	  error ("%qs with an always-false condition", code_name);
	  debug_generic_stmt (rhs1);
	  return true;
	}
      break;

    case WITH_SIZE_EXPR:
      error ("%qs RHS in assignment statement",
	     get_tree_code_name (rhs_code));
      debug_generic_expr (rhs1);
      return true;

    case OBJ_TYPE_REF:
      /* FIXME.  */
      return res;

    default:;
    }

  return res;
}

/* Verify the contents of a GIMPLE_ASSIGN STMT.  Returns true when there
   is a problem, otherwise false.  */

static bool
verify_gimple_assign (gassign *stmt)
{
  switch (gimple_assign_rhs_class (stmt))
    {
    case GIMPLE_SINGLE_RHS:
      return verify_gimple_assign_single (stmt);

    case GIMPLE_UNARY_RHS:
      return verify_gimple_assign_unary (stmt);

    case GIMPLE_BINARY_RHS:
      return verify_gimple_assign_binary (stmt);

    case GIMPLE_TERNARY_RHS:
      return verify_gimple_assign_ternary (stmt);

    default:
      gcc_unreachable ();
    }
}

/* Verify the contents of a GIMPLE_RETURN STMT.  Returns true when there
   is a problem, otherwise false.  */

static bool
verify_gimple_return (greturn *stmt)
{
  tree op = gimple_return_retval (stmt);
  tree restype = TREE_TYPE (TREE_TYPE (cfun->decl));

  /* We cannot test for present return values as we do not fix up missing
     return values from the original source.  */
  if (op == NULL)
    return false;

  if (!is_gimple_val (op)
      && TREE_CODE (op) != RESULT_DECL)
    {
      error ("invalid operand in return statement");
      debug_generic_stmt (op);
      return true;
    }

  if ((TREE_CODE (op) == RESULT_DECL
       && DECL_BY_REFERENCE (op))
      || (TREE_CODE (op) == SSA_NAME
	  && SSA_NAME_VAR (op)
	  && TREE_CODE (SSA_NAME_VAR (op)) == RESULT_DECL
	  && DECL_BY_REFERENCE (SSA_NAME_VAR (op))))
    op = TREE_TYPE (op);

  if (!useless_type_conversion_p (restype, TREE_TYPE (op)))
    {
      error ("invalid conversion in return statement");
      debug_generic_stmt (restype);
      debug_generic_stmt (TREE_TYPE (op));
      return true;
    }

  return false;
}


/* Verify the contents of a GIMPLE_GOTO STMT.  Returns true when there
   is a problem, otherwise false.  */

static bool
verify_gimple_goto (ggoto *stmt)
{
  tree dest = gimple_goto_dest (stmt);

  /* ???  We have two canonical forms of direct goto destinations, a
     bare LABEL_DECL and an ADDR_EXPR of a LABEL_DECL.  */
  if (TREE_CODE (dest) != LABEL_DECL
      && (!is_gimple_val (dest)
	  || !POINTER_TYPE_P (TREE_TYPE (dest))))
    {
      error ("goto destination is neither a label nor a pointer");
      return true;
    }

  return false;
}

/* Verify the contents of a GIMPLE_SWITCH STMT.  Returns true when there
   is a problem, otherwise false.  */

static bool
verify_gimple_switch (gswitch *stmt)
{
  unsigned int i, n;
  tree elt, prev_upper_bound = NULL_TREE;
  tree index_type, elt_type = NULL_TREE;

  if (!is_gimple_val (gimple_switch_index (stmt)))
    {
      error ("invalid operand to switch statement");
      debug_generic_stmt (gimple_switch_index (stmt));
      return true;
    }

  index_type = TREE_TYPE (gimple_switch_index (stmt));
  if (! INTEGRAL_TYPE_P (index_type))
    {
      error ("non-integral type switch statement");
      debug_generic_expr (index_type);
      return true;
    }

  elt = gimple_switch_label (stmt, 0);
  if (CASE_LOW (elt) != NULL_TREE
      || CASE_HIGH (elt) != NULL_TREE
      || CASE_CHAIN (elt) != NULL_TREE)
    {
      error ("invalid default case label in switch statement");
      debug_generic_expr (elt);
      return true;
    }

  n = gimple_switch_num_labels (stmt);
  for (i = 1; i < n; i++)
    {
      elt = gimple_switch_label (stmt, i);

      if (CASE_CHAIN (elt))
	{
	  error ("invalid %<CASE_CHAIN%>");
	  debug_generic_expr (elt);
	  return true;
	}
      if (! CASE_LOW (elt))
	{
	  error ("invalid case label in switch statement");
	  debug_generic_expr (elt);
	  return true;
	}
      if (CASE_HIGH (elt)
	  && ! tree_int_cst_lt (CASE_LOW (elt), CASE_HIGH (elt)))
	{
	  error ("invalid case range in switch statement");
	  debug_generic_expr (elt);
	  return true;
	}

      if (! elt_type)
	{
	  elt_type = TREE_TYPE (CASE_LOW (elt));
	  if (TYPE_PRECISION (index_type) < TYPE_PRECISION (elt_type))
	    {
	      error ("type precision mismatch in switch statement");
	      return true;
	    }
	}
      if (TREE_TYPE (CASE_LOW (elt)) != elt_type
          || (CASE_HIGH (elt) && TREE_TYPE (CASE_HIGH (elt)) != elt_type))
	{
	  error ("type mismatch for case label in switch statement");
	  debug_generic_expr (elt);
	  return true;
	}

      if (prev_upper_bound)
	{
	  if (! tree_int_cst_lt (prev_upper_bound, CASE_LOW (elt)))
	    {
	      error ("case labels not sorted in switch statement");
	      return true;
	    }
	}

      prev_upper_bound = CASE_HIGH (elt);
      if (! prev_upper_bound)
	prev_upper_bound = CASE_LOW (elt);
    }

  return false;
}

/* Verify a gimple debug statement STMT.
   Returns true if anything is wrong.  */

static bool
verify_gimple_debug (gimple *stmt ATTRIBUTE_UNUSED)
{
  /* There isn't much that could be wrong in a gimple debug stmt.  A
     gimple debug bind stmt, for example, maps a tree, that's usually
     a VAR_DECL or a PARM_DECL, but that could also be some scalarized
     component or member of an aggregate type, to another tree, that
     can be an arbitrary expression.  These stmts expand into debug
     insns, and are converted to debug notes by var-tracking.cc.  */
  return false;
}

/* Verify a gimple label statement STMT.
   Returns true if anything is wrong.  */

static bool
verify_gimple_label (glabel *stmt)
{
  tree decl = gimple_label_label (stmt);
  int uid;
  bool err = false;

  if (TREE_CODE (decl) != LABEL_DECL)
    return true;
  if (!DECL_NONLOCAL (decl) && !FORCED_LABEL (decl)
      && DECL_CONTEXT (decl) != current_function_decl)
    {
      error ("label context is not the current function declaration");
      err |= true;
    }

  uid = LABEL_DECL_UID (decl);
  if (cfun->cfg
      && (uid == -1
	  || (*label_to_block_map_for_fn (cfun))[uid] != gimple_bb (stmt)))
    {
      error ("incorrect entry in %<label_to_block_map%>");
      err |= true;
    }

  uid = EH_LANDING_PAD_NR (decl);
  if (uid)
    {
      eh_landing_pad lp = get_eh_landing_pad_from_number (uid);
      if (decl != lp->post_landing_pad)
	{
	  error ("incorrect setting of landing pad number");
	  err |= true;
	}
    }

  return err;
}

/* Verify a gimple cond statement STMT.
   Returns true if anything is wrong.  */

static bool
verify_gimple_cond (gcond *stmt)
{
  if (TREE_CODE_CLASS (gimple_cond_code (stmt)) != tcc_comparison)
    {
      error ("invalid comparison code in gimple cond");
      return true;
    }
  if (!(!gimple_cond_true_label (stmt)
	|| TREE_CODE (gimple_cond_true_label (stmt)) == LABEL_DECL)
      || !(!gimple_cond_false_label (stmt)
	   || TREE_CODE (gimple_cond_false_label (stmt)) == LABEL_DECL))
    {
      error ("invalid labels in gimple cond");
      return true;
    }

  return verify_gimple_comparison (boolean_type_node,
				   gimple_cond_lhs (stmt),
				   gimple_cond_rhs (stmt),
				   gimple_cond_code (stmt));
}

/* Verify the GIMPLE statement STMT.  Returns true if there is an
   error, otherwise false.  */

static bool
verify_gimple_stmt (gimple *stmt)
{
  switch (gimple_code (stmt))
    {
    case GIMPLE_ASSIGN:
      return verify_gimple_assign (as_a <gassign *> (stmt));

    case GIMPLE_LABEL:
      return verify_gimple_label (as_a <glabel *> (stmt));

    case GIMPLE_CALL:
      return verify_gimple_call (as_a <gcall *> (stmt));

    case GIMPLE_COND:
      return verify_gimple_cond (as_a <gcond *> (stmt));

    case GIMPLE_GOTO:
      return verify_gimple_goto (as_a <ggoto *> (stmt));

    case GIMPLE_SWITCH:
      return verify_gimple_switch (as_a <gswitch *> (stmt));

    case GIMPLE_RETURN:
      return verify_gimple_return (as_a <greturn *> (stmt));

    case GIMPLE_ASM:
      return false;

    case GIMPLE_TRANSACTION:
      return verify_gimple_transaction (as_a <gtransaction *> (stmt));

    /* Tuples that do not have tree operands.  */
    case GIMPLE_NOP:
    case GIMPLE_PREDICT:
    case GIMPLE_RESX:
    case GIMPLE_EH_DISPATCH:
    case GIMPLE_EH_MUST_NOT_THROW:
      return false;

    CASE_GIMPLE_OMP:
      /* OpenMP directives are validated by the FE and never operated
	 on by the optimizers.  Furthermore, GIMPLE_OMP_FOR may contain
	 non-gimple expressions when the main index variable has had
	 its address taken.  This does not affect the loop itself
	 because the header of an GIMPLE_OMP_FOR is merely used to determine
	 how to setup the parallel iteration.  */
      return false;

    case GIMPLE_ASSUME:
      return false;

    case GIMPLE_DEBUG:
      return verify_gimple_debug (stmt);

    default:
      gcc_unreachable ();
    }
}

/* Verify the contents of a GIMPLE_PHI.  Returns true if there is a problem,
   and false otherwise.  */

static bool
verify_gimple_phi (gphi *phi)
{
  bool err = false;
  unsigned i;
  tree phi_result = gimple_phi_result (phi);
  bool virtual_p;

  if (!phi_result)
    {
      error ("invalid %<PHI%> result");
      return true;
    }

  virtual_p = virtual_operand_p (phi_result);
  if (TREE_CODE (phi_result) != SSA_NAME
      || (virtual_p
	  && SSA_NAME_VAR (phi_result) != gimple_vop (cfun)))
    {
      error ("invalid %<PHI%> result");
      err = true;
    }

  for (i = 0; i < gimple_phi_num_args (phi); i++)
    {
      tree t = gimple_phi_arg_def (phi, i);

      if (!t)
	{
	  error ("missing %<PHI%> def");
	  err |= true;
	  continue;
	}
      /* Addressable variables do have SSA_NAMEs but they
	 are not considered gimple values.  */
      else if ((TREE_CODE (t) == SSA_NAME
		&& virtual_p != virtual_operand_p (t))
	       || (virtual_p
		   && (TREE_CODE (t) != SSA_NAME
		       || SSA_NAME_VAR (t) != gimple_vop (cfun)))
	       || (!virtual_p
		   && !is_gimple_val (t)))
	{
	  error ("invalid %<PHI%> argument");
	  debug_generic_expr (t);
	  err |= true;
	}
#ifdef ENABLE_TYPES_CHECKING
      if (!useless_type_conversion_p (TREE_TYPE (phi_result), TREE_TYPE (t)))
	{
	  error ("incompatible types in %<PHI%> argument %u", i);
	  debug_generic_stmt (TREE_TYPE (phi_result));
	  debug_generic_stmt (TREE_TYPE (t));
	  err |= true;
	}
#endif
    }

  return err;
}

/* Verify the GIMPLE statements inside the sequence STMTS.  */

static bool
verify_gimple_in_seq_2 (gimple_seq stmts)
{
  gimple_stmt_iterator ittr;
  bool err = false;

  for (ittr = gsi_start (stmts); !gsi_end_p (ittr); gsi_next (&ittr))
    {
      gimple *stmt = gsi_stmt (ittr);

      switch (gimple_code (stmt))
        {
	case GIMPLE_BIND:
	  err |= verify_gimple_in_seq_2 (
                   gimple_bind_body (as_a <gbind *> (stmt)));
	  break;

	case GIMPLE_TRY:
	  err |= verify_gimple_in_seq_2 (gimple_try_eval (stmt));
	  err |= verify_gimple_in_seq_2 (gimple_try_cleanup (stmt));
	  break;

	case GIMPLE_EH_FILTER:
	  err |= verify_gimple_in_seq_2 (gimple_eh_filter_failure (stmt));
	  break;

	case GIMPLE_EH_ELSE:
	  {
	    geh_else *eh_else = as_a <geh_else *> (stmt);
	    err |= verify_gimple_in_seq_2 (gimple_eh_else_n_body (eh_else));
	    err |= verify_gimple_in_seq_2 (gimple_eh_else_e_body (eh_else));
	  }
	  break;

	case GIMPLE_CATCH:
	  err |= verify_gimple_in_seq_2 (gimple_catch_handler (
					   as_a <gcatch *> (stmt)));
	  break;

	case GIMPLE_ASSUME:
	  err |= verify_gimple_in_seq_2 (gimple_assume_body (stmt));
	  break;

	case GIMPLE_TRANSACTION:
	  err |= verify_gimple_transaction (as_a <gtransaction *> (stmt));
	  break;

	default:
	  {
	    bool err2 = verify_gimple_stmt (stmt);
	    if (err2)
	      debug_gimple_stmt (stmt);
	    err |= err2;
	  }
	}
    }

  return err;
}

/* Verify the contents of a GIMPLE_TRANSACTION.  Returns true if there
   is a problem, otherwise false.  */

static bool
verify_gimple_transaction (gtransaction *stmt)
{
  tree lab;

  lab = gimple_transaction_label_norm (stmt);
  if (lab != NULL && TREE_CODE (lab) != LABEL_DECL)
    return true;
  lab = gimple_transaction_label_uninst (stmt);
  if (lab != NULL && TREE_CODE (lab) != LABEL_DECL)
    return true;
  lab = gimple_transaction_label_over (stmt);
  if (lab != NULL && TREE_CODE (lab) != LABEL_DECL)
    return true;

  return verify_gimple_in_seq_2 (gimple_transaction_body (stmt));
}


/* Verify the GIMPLE statements inside the statement list STMTS.  */

DEBUG_FUNCTION bool
verify_gimple_in_seq (gimple_seq stmts, bool ice)
{
  timevar_push (TV_TREE_STMT_VERIFY);
  bool res = verify_gimple_in_seq_2 (stmts);
  if (res && ice)
    internal_error ("%<verify_gimple%> failed");
  timevar_pop (TV_TREE_STMT_VERIFY);
  return res;
}

/* Return true when the T can be shared.  */

static bool
tree_node_can_be_shared (tree t)
{
  if (IS_TYPE_OR_DECL_P (t)
      || TREE_CODE (t) == SSA_NAME
      || TREE_CODE (t) == IDENTIFIER_NODE
      || TREE_CODE (t) == CASE_LABEL_EXPR
      || is_gimple_min_invariant (t))
    return true;

  if (t == error_mark_node)
    return true;

  return false;
}

/* Called via walk_tree.  Verify tree sharing.  */

static tree
verify_node_sharing_1 (tree *tp, int *walk_subtrees, void *data)
{
  hash_set<void *> *visited = (hash_set<void *> *) data;

  if (tree_node_can_be_shared (*tp))
    {
      *walk_subtrees = false;
      return NULL;
    }

  if (visited->add (*tp))
    return *tp;

  return NULL;
}

/* Called via walk_gimple_stmt.  Verify tree sharing.  */

static tree
verify_node_sharing (tree *tp, int *walk_subtrees, void *data)
{
  struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
  return verify_node_sharing_1 (tp, walk_subtrees, wi->info);
}

static bool eh_error_found;
bool
verify_eh_throw_stmt_node (gimple *const &stmt, const int &,
			   hash_set<gimple *> *visited)
{
  if (!visited->contains (stmt))
    {
      error ("dead statement in EH table");
      debug_gimple_stmt (stmt);
      eh_error_found = true;
    }
  return true;
}

/* Verify if the location LOCs block is in BLOCKS.  */

static bool
verify_location (hash_set<tree> *blocks, location_t loc)
{
  tree block = LOCATION_BLOCK (loc);
  if (block != NULL_TREE
      && !blocks->contains (block))
    {
      error ("location references block not in block tree");
      return true;
    }
  if (block != NULL_TREE)
    return verify_location (blocks, BLOCK_SOURCE_LOCATION (block));
  return false;
}

/* Called via walk_tree.  Verify that expressions have no blocks.  */

static tree
verify_expr_no_block (tree *tp, int *walk_subtrees, void *)
{
  if (!EXPR_P (*tp))
    {
      *walk_subtrees = false;
      return NULL;
    }

  location_t loc = EXPR_LOCATION (*tp);
  if (LOCATION_BLOCK (loc) != NULL)
    return *tp;

  return NULL;
}

/* Called via walk_tree.  Verify locations of expressions.  */

static tree
verify_expr_location_1 (tree *tp, int *walk_subtrees, void *data)
{
  hash_set<tree> *blocks = (hash_set<tree> *) data;
  tree t = *tp;

  /* ???  This doesn't really belong here but there's no good place to
     stick this remainder of old verify_expr.  */
  /* ???  This barfs on debug stmts which contain binds to vars with
     different function context.  */
#if 0
  if (VAR_P (t)
      || TREE_CODE (t) == PARM_DECL
      || TREE_CODE (t) == RESULT_DECL)
    {
      tree context = decl_function_context (t);
      if (context != cfun->decl
	  && !SCOPE_FILE_SCOPE_P (context)
	  && !TREE_STATIC (t)
	  && !DECL_EXTERNAL (t))
	{
	  error ("local declaration from a different function");
	  return t;
	}
    }
#endif

  if (VAR_P (t) && DECL_HAS_DEBUG_EXPR_P (t))
    {
      tree x = DECL_DEBUG_EXPR (t);
      tree addr = walk_tree (&x, verify_expr_no_block, NULL, NULL);
      if (addr)
	return addr;
    }
  if ((VAR_P (t)
       || TREE_CODE (t) == PARM_DECL
       || TREE_CODE (t) == RESULT_DECL)
      && DECL_HAS_VALUE_EXPR_P (t))
    {
      tree x = DECL_VALUE_EXPR (t);
      tree addr = walk_tree (&x, verify_expr_no_block, NULL, NULL);
      if (addr)
	return addr;
    }

  if (!EXPR_P (t))
    {
      *walk_subtrees = false;
      return NULL;
    }

  location_t loc = EXPR_LOCATION (t);
  if (verify_location (blocks, loc))
    return t;

  return NULL;
}

/* Called via walk_gimple_op.  Verify locations of expressions.  */

static tree
verify_expr_location (tree *tp, int *walk_subtrees, void *data)
{
  struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
  return verify_expr_location_1 (tp, walk_subtrees, wi->info);
}

/* Insert all subblocks of BLOCK into BLOCKS and recurse.  */

static void
collect_subblocks (hash_set<tree> *blocks, tree block)
{
  tree t;
  for (t = BLOCK_SUBBLOCKS (block); t; t = BLOCK_CHAIN (t))
    {
      blocks->add (t);
      collect_subblocks (blocks, t);
    }
}

/* Disable warnings about missing quoting in GCC diagnostics for
   the verification errors.  Their format strings don't follow
   GCC diagnostic conventions and trigger an ICE in the end.  */
#if __GNUC__ >= 10
#  pragma GCC diagnostic push
#  pragma GCC diagnostic ignored "-Wformat-diag"
#endif

/* Verify the GIMPLE statements in the CFG of FN.  */

DEBUG_FUNCTION bool
verify_gimple_in_cfg (struct function *fn, bool verify_nothrow, bool ice)
{
  basic_block bb;
  bool err = false;

  timevar_push (TV_TREE_STMT_VERIFY);
  hash_set<void *> visited;
  hash_set<gimple *> visited_throwing_stmts;

  /* Collect all BLOCKs referenced by the BLOCK tree of FN.  */
  hash_set<tree> blocks;
  if (DECL_INITIAL (fn->decl))
    {
      blocks.add (DECL_INITIAL (fn->decl));
      collect_subblocks (&blocks, DECL_INITIAL (fn->decl));
    }

  FOR_EACH_BB_FN (bb, fn)
    {
      gimple_stmt_iterator gsi;
      edge_iterator ei;
      edge e;

      for (gphi_iterator gpi = gsi_start_phis (bb);
	   !gsi_end_p (gpi);
	   gsi_next (&gpi))
	{
	  gphi *phi = gpi.phi ();
	  bool err2 = false;
	  unsigned i;

	  if (gimple_bb (phi) != bb)
	    {
	      error ("gimple_bb (phi) is set to a wrong basic block");
	      err2 = true;
	    }

	  err2 |= verify_gimple_phi (phi);

	  /* Only PHI arguments have locations.  */
	  if (gimple_location (phi) != UNKNOWN_LOCATION)
	    {
	      error ("PHI node with location");
	      err2 = true;
	    }

	  for (i = 0; i < gimple_phi_num_args (phi); i++)
	    {
	      tree arg = gimple_phi_arg_def (phi, i);
	      tree addr = walk_tree (&arg, verify_node_sharing_1,
				     &visited, NULL);
	      if (addr)
		{
		  error ("incorrect sharing of tree nodes");
		  debug_generic_expr (addr);
		  err2 |= true;
		}
	      location_t loc = gimple_phi_arg_location (phi, i);
	      if (virtual_operand_p (gimple_phi_result (phi))
		  && loc != UNKNOWN_LOCATION)
		{
		  error ("virtual PHI with argument locations");
		  err2 = true;
		}
	      addr = walk_tree (&arg, verify_expr_location_1, &blocks, NULL);
	      if (addr)
		{
		  debug_generic_expr (addr);
		  err2 = true;
		}
	      err2 |= verify_location (&blocks, loc);
	    }

	  if (err2)
	    debug_gimple_stmt (phi);
	  err |= err2;
	}

      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
	{
	  gimple *stmt = gsi_stmt (gsi);
	  bool err2 = false;
	  struct walk_stmt_info wi;
	  tree addr;
	  int lp_nr;

	  if (gimple_bb (stmt) != bb)
	    {
	      error ("gimple_bb (stmt) is set to a wrong basic block");
	      err2 = true;
	    }

	  err2 |= verify_gimple_stmt (stmt);
	  err2 |= verify_location (&blocks, gimple_location (stmt));

	  memset (&wi, 0, sizeof (wi));
	  wi.info = (void *) &visited;
	  addr = walk_gimple_op (stmt, verify_node_sharing, &wi);
	  if (addr)
	    {
	      error ("incorrect sharing of tree nodes");
	      debug_generic_expr (addr);
	      err2 |= true;
	    }

	  memset (&wi, 0, sizeof (wi));
	  wi.info = (void *) &blocks;
	  addr = walk_gimple_op (stmt, verify_expr_location, &wi);
	  if (addr)
	    {
	      debug_generic_expr (addr);
	      err2 |= true;
	    }

	  /* If the statement is marked as part of an EH region, then it is
	     expected that the statement could throw.  Verify that when we
	     have optimizations that simplify statements such that we prove
	     that they cannot throw, that we update other data structures
	     to match.  */
	  lp_nr = lookup_stmt_eh_lp (stmt);
	  if (lp_nr != 0)
	    visited_throwing_stmts.add (stmt);
	  if (lp_nr > 0)
	    {
	      if (!stmt_could_throw_p (cfun, stmt))
		{
		  if (verify_nothrow)
		    {
		      error ("statement marked for throw, but doesn%'t");
		      err2 |= true;
		    }
		}
	      else if (!gsi_one_before_end_p (gsi))
		{
		  error ("statement marked for throw in middle of block");
		  err2 |= true;
		}
	    }

	  if (err2)
	    debug_gimple_stmt (stmt);
	  err |= err2;
	}

      FOR_EACH_EDGE (e, ei, bb->succs)
	if (e->goto_locus != UNKNOWN_LOCATION)
	  err |= verify_location (&blocks, e->goto_locus);
    }

  hash_map<gimple *, int> *eh_table = get_eh_throw_stmt_table (cfun);
  eh_error_found = false;
  if (eh_table)
    eh_table->traverse<hash_set<gimple *> *, verify_eh_throw_stmt_node>
      (&visited_throwing_stmts);

  if (ice && (err || eh_error_found))
    internal_error ("verify_gimple failed");

  verify_histograms ();
  timevar_pop (TV_TREE_STMT_VERIFY);

  return (err || eh_error_found);
}


/* Verifies that the flow information is OK.  */

static int
gimple_verify_flow_info (void)
{
  int err = 0;
  basic_block bb;
  gimple_stmt_iterator gsi;
  gimple *stmt;
  edge e;
  edge_iterator ei;

  if (ENTRY_BLOCK_PTR_FOR_FN (cfun)->il.gimple.seq
      || ENTRY_BLOCK_PTR_FOR_FN (cfun)->il.gimple.phi_nodes)
    {
      error ("ENTRY_BLOCK has IL associated with it");
      err = 1;
    }

  if (EXIT_BLOCK_PTR_FOR_FN (cfun)->il.gimple.seq
      || EXIT_BLOCK_PTR_FOR_FN (cfun)->il.gimple.phi_nodes)
    {
      error ("EXIT_BLOCK has IL associated with it");
      err = 1;
    }

  FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
    if (e->flags & EDGE_FALLTHRU)
      {
	error ("fallthru to exit from bb %d", e->src->index);
	err = 1;
      }

  FOR_EACH_BB_FN (bb, cfun)
    {
      bool found_ctrl_stmt = false;

      stmt = NULL;

      /* Skip labels on the start of basic block.  */
      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
	{
	  tree label;
	  gimple *prev_stmt = stmt;

	  stmt = gsi_stmt (gsi);

	  if (gimple_code (stmt) != GIMPLE_LABEL)
	    break;

	  label = gimple_label_label (as_a <glabel *> (stmt));
	  if (prev_stmt && DECL_NONLOCAL (label))
	    {
	      error ("nonlocal label %qD is not first in a sequence "
		     "of labels in bb %d", label, bb->index);
	      err = 1;
	    }

	  if (prev_stmt && EH_LANDING_PAD_NR (label) != 0)
	    {
	      error ("EH landing pad label %qD is not first in a sequence "
		     "of labels in bb %d", label, bb->index);
	      err = 1;
	    }

	  if (label_to_block (cfun, label) != bb)
	    {
	      error ("label %qD to block does not match in bb %d",
		     label, bb->index);
	      err = 1;
	    }

	  if (decl_function_context (label) != current_function_decl)
	    {
	      error ("label %qD has incorrect context in bb %d",
		     label, bb->index);
	      err = 1;
	    }
	}

      /* Verify that body of basic block BB is free of control flow.  */
      bool seen_nondebug_stmt = false;
      for (; !gsi_end_p (gsi); gsi_next (&gsi))
	{
	  gimple *stmt = gsi_stmt (gsi);

	  if (found_ctrl_stmt)
	    {
	      error ("control flow in the middle of basic block %d",
		     bb->index);
	      err = 1;
	    }

	  if (stmt_ends_bb_p (stmt))
	    found_ctrl_stmt = true;

	  if (glabel *label_stmt = dyn_cast <glabel *> (stmt))
	    {
	      error ("label %qD in the middle of basic block %d",
		     gimple_label_label (label_stmt), bb->index);
	      err = 1;
	    }

	  /* Check that no statements appear between a returns_twice call
	     and its associated abnormal edge.  */
	  if (gimple_code (stmt) == GIMPLE_CALL
	      && gimple_call_flags (stmt) & ECF_RETURNS_TWICE)
	    {
	      const char *misplaced = NULL;
	      /* TM is an exception: it points abnormal edges just after the
		 call that starts a transaction, i.e. it must end the BB.  */
	      if (gimple_call_builtin_p (stmt, BUILT_IN_TM_START))
		{
		  if (single_succ_p (bb)
		      && bb_has_abnormal_pred (single_succ (bb))
		      && !gsi_one_nondebug_before_end_p (gsi))
		    misplaced = "not last";
		}
	      else
		{
		  if (seen_nondebug_stmt
		      && bb_has_abnormal_pred (bb))
		    misplaced = "not first";
		}
	      if (misplaced)
		{
		  error ("returns_twice call is %s in basic block %d",
			 misplaced, bb->index);
		  print_gimple_stmt (stderr, stmt, 0, TDF_SLIM);
		  err = 1;
		}
	    }
	  if (!is_gimple_debug (stmt))
	    seen_nondebug_stmt = true;
	}

      gsi = gsi_last_nondebug_bb (bb);
      if (gsi_end_p (gsi))
	continue;

      stmt = gsi_stmt (gsi);

      if (gimple_code (stmt) == GIMPLE_LABEL)
	continue;

      err |= verify_eh_edges (stmt);

      if (is_ctrl_stmt (stmt))
	{
	  FOR_EACH_EDGE (e, ei, bb->succs)
	    if (e->flags & EDGE_FALLTHRU)
	      {
		error ("fallthru edge after a control statement in bb %d",
		       bb->index);
		err = 1;
	      }
	}

      if (gimple_code (stmt) != GIMPLE_COND)
	{
	  /* Verify that there are no edges with EDGE_TRUE/FALSE_FLAG set
	     after anything else but if statement.  */
	  FOR_EACH_EDGE (e, ei, bb->succs)
	    if (e->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE))
	      {
		error ("true/false edge after a non-GIMPLE_COND in bb %d",
		       bb->index);
		err = 1;
	      }
	}

      switch (gimple_code (stmt))
	{
	case GIMPLE_COND:
	  {
	    edge true_edge;
	    edge false_edge;

	    extract_true_false_edges_from_block (bb, &true_edge, &false_edge);

	    if (!true_edge
		|| !false_edge
		|| !(true_edge->flags & EDGE_TRUE_VALUE)
		|| !(false_edge->flags & EDGE_FALSE_VALUE)
		|| (true_edge->flags & (EDGE_FALLTHRU | EDGE_ABNORMAL))
		|| (false_edge->flags & (EDGE_FALLTHRU | EDGE_ABNORMAL))
		|| EDGE_COUNT (bb->succs) >= 3)
	      {
		error ("wrong outgoing edge flags at end of bb %d",
		       bb->index);
		err = 1;
	      }
	  }
	  break;

	case GIMPLE_GOTO:
	  if (simple_goto_p (stmt))
	    {
	      error ("explicit goto at end of bb %d", bb->index);
	      err = 1;
	    }
	  else
	    {
	      /* FIXME.  We should double check that the labels in the
		 destination blocks have their address taken.  */
	      FOR_EACH_EDGE (e, ei, bb->succs)
		if ((e->flags & (EDGE_FALLTHRU | EDGE_TRUE_VALUE
				 | EDGE_FALSE_VALUE))
		    || !(e->flags & EDGE_ABNORMAL))
		  {
		    error ("wrong outgoing edge flags at end of bb %d",
			   bb->index);
		    err = 1;
		  }
	    }
	  break;

	case GIMPLE_CALL:
	  if (!gimple_call_builtin_p (stmt, BUILT_IN_RETURN))
	    break;
	  /* fallthru */
	case GIMPLE_RETURN:
	  if (!single_succ_p (bb)
	      || (single_succ_edge (bb)->flags
		  & (EDGE_FALLTHRU | EDGE_ABNORMAL
		     | EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)))
	    {
	      error ("wrong outgoing edge flags at end of bb %d", bb->index);
	      err = 1;
	    }
	  if (single_succ (bb) != EXIT_BLOCK_PTR_FOR_FN (cfun))
	    {
	      error ("return edge does not point to exit in bb %d",
		     bb->index);
	      err = 1;
	    }
	  break;

	case GIMPLE_SWITCH:
	  {
	    gswitch *switch_stmt = as_a <gswitch *> (stmt);
	    tree prev;
	    edge e;
	    size_t i, n;

	    n = gimple_switch_num_labels (switch_stmt);

	    /* Mark all the destination basic blocks.  */
	    for (i = 0; i < n; ++i)
	      {
		basic_block label_bb = gimple_switch_label_bb (cfun, switch_stmt, i);
		gcc_assert (!label_bb->aux || label_bb->aux == (void *)1);
		label_bb->aux = (void *)1;
	      }

	    /* Verify that the case labels are sorted.  */
	    prev = gimple_switch_label (switch_stmt, 0);
	    for (i = 1; i < n; ++i)
	      {
		tree c = gimple_switch_label (switch_stmt, i);
		if (!CASE_LOW (c))
		  {
		    error ("found default case not at the start of "
			   "case vector");
		    err = 1;
		    continue;
		  }
		if (CASE_LOW (prev)
		    && !tree_int_cst_lt (CASE_LOW (prev), CASE_LOW (c)))
		  {
		    error ("case labels not sorted: ");
		    print_generic_expr (stderr, prev);
		    fprintf (stderr," is greater than ");
		    print_generic_expr (stderr, c);
		    fprintf (stderr," but comes before it.\n");
		    err = 1;
		  }
		prev = c;
	      }
	    /* VRP will remove the default case if it can prove it will
	       never be executed.  So do not verify there always exists
	       a default case here.  */

	    FOR_EACH_EDGE (e, ei, bb->succs)
	      {
		if (!e->dest->aux)
		  {
		    error ("extra outgoing edge %d->%d",
			   bb->index, e->dest->index);
		    err = 1;
		  }

		e->dest->aux = (void *)2;
		if ((e->flags & (EDGE_FALLTHRU | EDGE_ABNORMAL
				 | EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)))
		  {
		    error ("wrong outgoing edge flags at end of bb %d",
			   bb->index);
		    err = 1;
		  }
	      }

	    /* Check that we have all of them.  */
	    for (i = 0; i < n; ++i)
	      {
		basic_block label_bb = gimple_switch_label_bb (cfun,
							       switch_stmt, i);

		if (label_bb->aux != (void *)2)
		  {
		    error ("missing edge %i->%i", bb->index, label_bb->index);
		    err = 1;
		  }
	      }

	    FOR_EACH_EDGE (e, ei, bb->succs)
	      e->dest->aux = (void *)0;
	  }
	  break;

	case GIMPLE_EH_DISPATCH:
	  err |= verify_eh_dispatch_edge (as_a <geh_dispatch *> (stmt));
	  break;

	default:
	  break;
	}
    }

  if (dom_info_state (CDI_DOMINATORS) >= DOM_NO_FAST_QUERY)
    verify_dominators (CDI_DOMINATORS);

  return err;
}

#if __GNUC__ >= 10
#  pragma GCC diagnostic pop
#endif

/* Updates phi nodes after creating a forwarder block joined
   by edge FALLTHRU.  */

static void
gimple_make_forwarder_block (edge fallthru)
{
  edge e;
  edge_iterator ei;
  basic_block dummy, bb;
  tree var;
  gphi_iterator gsi;
  bool forward_location_p;

  dummy = fallthru->src;
  bb = fallthru->dest;

  if (single_pred_p (bb))
    return;

  /* We can forward location info if we have only one predecessor.  */
  forward_location_p = single_pred_p (dummy);

  /* If we redirected a branch we must create new PHI nodes at the
     start of BB.  */
  for (gsi = gsi_start_phis (dummy); !gsi_end_p (gsi); gsi_next (&gsi))
    {
      gphi *phi, *new_phi;

      phi = gsi.phi ();
      var = gimple_phi_result (phi);
      new_phi = create_phi_node (var, bb);
      gimple_phi_set_result (phi, copy_ssa_name (var, phi));
      add_phi_arg (new_phi, gimple_phi_result (phi), fallthru,
		   forward_location_p
		   ? gimple_phi_arg_location (phi, 0) : UNKNOWN_LOCATION);
    }

  /* Add the arguments we have stored on edges.  */
  FOR_EACH_EDGE (e, ei, bb->preds)
    {
      if (e == fallthru)
	continue;

      flush_pending_stmts (e);
    }
}


/* Return a non-special label in the head of basic block BLOCK.
   Create one if it doesn't exist.  */

tree
gimple_block_label (basic_block bb)
{
  gimple_stmt_iterator i, s = gsi_start_bb (bb);
  bool first = true;
  tree label;
  glabel *stmt;

  for (i = s; !gsi_end_p (i); first = false, gsi_next (&i))
    {
      stmt = dyn_cast <glabel *> (gsi_stmt (i));
      if (!stmt)
	break;
      label = gimple_label_label (stmt);
      if (!DECL_NONLOCAL (label))
	{
	  if (!first)
	    gsi_move_before (&i, &s);
	  return label;
	}
    }

  label = create_artificial_label (UNKNOWN_LOCATION);
  stmt = gimple_build_label (label);
  gsi_insert_before (&s, stmt, GSI_NEW_STMT);
  return label;
}


/* Attempt to perform edge redirection by replacing a possibly complex
   jump instruction by a goto or by removing the jump completely.
   This can apply only if all edges now point to the same block.  The
   parameters and return values are equivalent to
   redirect_edge_and_branch.  */

static edge
gimple_try_redirect_by_replacing_jump (edge e, basic_block target)
{
  basic_block src = e->src;
  gimple_stmt_iterator i;
  gimple *stmt;

  /* We can replace or remove a complex jump only when we have exactly
     two edges.  */
  if (EDGE_COUNT (src->succs) != 2
      /* Verify that all targets will be TARGET.  Specifically, the
	 edge that is not E must also go to TARGET.  */
      || EDGE_SUCC (src, EDGE_SUCC (src, 0) == e)->dest != target)
    return NULL;

  i = gsi_last_bb (src);
  if (gsi_end_p (i))
    return NULL;

  stmt = gsi_stmt (i);

  if (gimple_code (stmt) == GIMPLE_COND || gimple_code (stmt) == GIMPLE_SWITCH)
    {
      gsi_remove (&i, true);
      e = ssa_redirect_edge (e, target);
      e->flags = EDGE_FALLTHRU;
      return e;
    }

  return NULL;
}


/* Redirect E to DEST.  Return NULL on failure.  Otherwise, return the
   edge representing the redirected branch.  */

static edge
gimple_redirect_edge_and_branch (edge e, basic_block dest)
{
  basic_block bb = e->src;
  gimple_stmt_iterator gsi;
  edge ret;
  gimple *stmt;

  if (e->flags & EDGE_ABNORMAL)
    return NULL;

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

  if (e->flags & EDGE_EH)
    return redirect_eh_edge (e, dest);

  if (e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun))
    {
      ret = gimple_try_redirect_by_replacing_jump (e, dest);
      if (ret)
	return ret;
    }

  gsi = gsi_last_nondebug_bb (bb);
  stmt = gsi_end_p (gsi) ? NULL : gsi_stmt (gsi);

  switch (stmt ? gimple_code (stmt) : GIMPLE_ERROR_MARK)
    {
    case GIMPLE_COND:
      /* For COND_EXPR, we only need to redirect the edge.  */
      break;

    case GIMPLE_GOTO:
      /* No non-abnormal edges should lead from a non-simple goto, and
	 simple ones should be represented implicitly.  */
      gcc_unreachable ();

    case GIMPLE_SWITCH:
      {
	gswitch *switch_stmt = as_a <gswitch *> (stmt);
	tree label = gimple_block_label (dest);
        tree cases = get_cases_for_edge (e, switch_stmt);

	/* If we have a list of cases associated with E, then use it
	   as it's a lot faster than walking the entire case vector.  */
	if (cases)
	  {
	    edge e2 = find_edge (e->src, dest);
	    tree last, first;

	    first = cases;
	    while (cases)
	      {
		last = cases;
		CASE_LABEL (cases) = label;
		cases = CASE_CHAIN (cases);
	      }

	    /* If there was already an edge in the CFG, then we need
	       to move all the cases associated with E to E2.  */
	    if (e2)
	      {
		tree cases2 = get_cases_for_edge (e2, switch_stmt);

		CASE_CHAIN (last) = CASE_CHAIN (cases2);
		CASE_CHAIN (cases2) = first;
	      }
	    bitmap_set_bit (touched_switch_bbs, gimple_bb (stmt)->index);
	  }
	else
	  {
	    size_t i, n = gimple_switch_num_labels (switch_stmt);

	    for (i = 0; i < n; i++)
	      {
		tree elt = gimple_switch_label (switch_stmt, i);
		if (label_to_block (cfun, CASE_LABEL (elt)) == e->dest)
		  CASE_LABEL (elt) = label;
	      }
	  }
      }
      break;

    case GIMPLE_ASM:
      {
	gasm *asm_stmt = as_a <gasm *> (stmt);
	int i, n = gimple_asm_nlabels (asm_stmt);
	tree label = NULL;

	for (i = 0; i < n; ++i)
	  {
	    tree cons = gimple_asm_label_op (asm_stmt, i);
	    if (label_to_block (cfun, TREE_VALUE (cons)) == e->dest)
	      {
		if (!label)
		  label = gimple_block_label (dest);
		TREE_VALUE (cons) = label;
	      }
	  }

	/* If we didn't find any label matching the former edge in the
	   asm labels, we must be redirecting the fallthrough
	   edge.  */
	gcc_assert (label || (e->flags & EDGE_FALLTHRU));
      }
      break;

    case GIMPLE_RETURN:
      gsi_remove (&gsi, true);
      e->flags |= EDGE_FALLTHRU;
      break;

    case GIMPLE_OMP_RETURN:
    case GIMPLE_OMP_CONTINUE:
    case GIMPLE_OMP_SECTIONS_SWITCH:
    case GIMPLE_OMP_FOR:
      /* The edges from OMP constructs can be simply redirected.  */
      break;

    case GIMPLE_EH_DISPATCH:
      if (!(e->flags & EDGE_FALLTHRU))
	redirect_eh_dispatch_edge (as_a <geh_dispatch *> (stmt), e, dest);
      break;

    case GIMPLE_TRANSACTION:
      if (e->flags & EDGE_TM_ABORT)
	gimple_transaction_set_label_over (as_a <gtransaction *> (stmt),
				           gimple_block_label (dest));
      else if (e->flags & EDGE_TM_UNINSTRUMENTED)
	gimple_transaction_set_label_uninst (as_a <gtransaction *> (stmt),
				             gimple_block_label (dest));
      else
	gimple_transaction_set_label_norm (as_a <gtransaction *> (stmt),
				           gimple_block_label (dest));
      break;

    default:
      /* Otherwise it must be a fallthru edge, and we don't need to
	 do anything besides redirecting it.  */
      gcc_assert (e->flags & EDGE_FALLTHRU);
      break;
    }

  /* Update/insert PHI nodes as necessary.  */

  /* Now update the edges in the CFG.  */
  e = ssa_redirect_edge (e, dest);

  return e;
}

/* Returns true if it is possible to remove edge E by redirecting
   it to the destination of the other edge from E->src.  */

static bool
gimple_can_remove_branch_p (const_edge e)
{
  if (e->flags & (EDGE_ABNORMAL | EDGE_EH))
    return false;

  return true;
}

/* Simple wrapper, as we can always redirect fallthru edges.  */

static basic_block
gimple_redirect_edge_and_branch_force (edge e, basic_block dest)
{
  e = gimple_redirect_edge_and_branch (e, dest);
  gcc_assert (e);

  return NULL;
}


/* Splits basic block BB after statement STMT (but at least after the
   labels).  If STMT is NULL, BB is split just after the labels.  */

static basic_block
gimple_split_block (basic_block bb, void *stmt)
{
  gimple_stmt_iterator gsi;
  gimple_stmt_iterator gsi_tgt;
  gimple_seq list;
  basic_block new_bb;
  edge e;
  edge_iterator ei;

  new_bb = create_empty_bb (bb);

  /* Redirect the outgoing edges.  */
  new_bb->succs = bb->succs;
  bb->succs = NULL;
  FOR_EACH_EDGE (e, ei, new_bb->succs)
    e->src = new_bb;

  /* Get a stmt iterator pointing to the first stmt to move.  */
  if (!stmt || gimple_code ((gimple *) stmt) == GIMPLE_LABEL)
    gsi = gsi_after_labels (bb);
  else
    {
      gsi = gsi_for_stmt ((gimple *) stmt);
      gsi_next (&gsi);
    }
 
  /* Move everything from GSI to the new basic block.  */
  if (gsi_end_p (gsi))
    return new_bb;

  /* Split the statement list - avoid re-creating new containers as this
     brings ugly quadratic memory consumption in the inliner.
     (We are still quadratic since we need to update stmt BB pointers,
     sadly.)  */
  gsi_split_seq_before (&gsi, &list);
  set_bb_seq (new_bb, list);
  for (gsi_tgt = gsi_start (list);
       !gsi_end_p (gsi_tgt); gsi_next (&gsi_tgt))
    gimple_set_bb (gsi_stmt (gsi_tgt), new_bb);

  return new_bb;
}


/* Moves basic block BB after block AFTER.  */

static bool
gimple_move_block_after (basic_block bb, basic_block after)
{
  if (bb->prev_bb == after)
    return true;

  unlink_block (bb);
  link_block (bb, after);

  return true;
}


/* Return TRUE if block BB has no executable statements, otherwise return
   FALSE.  */

static bool
gimple_empty_block_p (basic_block bb)
{
  /* BB must have no executable statements.  */
  gimple_stmt_iterator gsi = gsi_after_labels (bb);
  if (phi_nodes (bb))
    return false;
  while (!gsi_end_p (gsi))
    {
      gimple *stmt = gsi_stmt (gsi);
      if (is_gimple_debug (stmt))
	;
      else if (gimple_code (stmt) == GIMPLE_NOP
	       || gimple_code (stmt) == GIMPLE_PREDICT)
	;
      else
	return false;
      gsi_next (&gsi);
    }
  return true;
}


/* Split a basic block if it ends with a conditional branch and if the
   other part of the block is not empty.  */

static basic_block
gimple_split_block_before_cond_jump (basic_block bb)
{
  gimple *last, *split_point;
  gimple_stmt_iterator gsi = gsi_last_nondebug_bb (bb);
  if (gsi_end_p (gsi))
    return NULL;
  last = gsi_stmt (gsi);
  if (gimple_code (last) != GIMPLE_COND
      && gimple_code (last) != GIMPLE_SWITCH)
    return NULL;
  gsi_prev (&gsi);
  split_point = gsi_stmt (gsi);
  return split_block (bb, split_point)->dest;
}


/* Return true if basic_block can be duplicated.  */

static bool
gimple_can_duplicate_bb_p (const_basic_block bb)
{
  gimple *last = last_stmt (CONST_CAST_BB (bb));

  /* Do checks that can only fail for the last stmt, to minimize the work in the
     stmt loop.  */
  if (last) {
    /* A transaction is a single entry multiple exit region.  It
       must be duplicated in its entirety or not at all.  */
    if (gimple_code (last) == GIMPLE_TRANSACTION)
      return false;

    /* An IFN_UNIQUE call must be duplicated as part of its group,
       or not at all.  */
    if (is_gimple_call (last)
	&& gimple_call_internal_p (last)
	&& gimple_call_internal_unique_p (last))
      return false;
  }

  for (gimple_stmt_iterator gsi = gsi_start_bb (CONST_CAST_BB (bb));
       !gsi_end_p (gsi); gsi_next (&gsi))
    {
      gimple *g = gsi_stmt (gsi);

      /* Prohibit duplication of returns_twice calls, otherwise associated
	 abnormal edges also need to be duplicated properly.
	 An IFN_GOMP_SIMT_ENTER_ALLOC/IFN_GOMP_SIMT_EXIT call must be
	 duplicated as part of its group, or not at all.
	 The IFN_GOMP_SIMT_VOTE_ANY and IFN_GOMP_SIMT_XCHG_* are part of such a
	 group, so the same holds there.  */
      if (is_gimple_call (g)
	  && (gimple_call_flags (g) & ECF_RETURNS_TWICE
	      || gimple_call_internal_p (g, IFN_GOMP_SIMT_ENTER_ALLOC)
	      || gimple_call_internal_p (g, IFN_GOMP_SIMT_EXIT)
	      || gimple_call_internal_p (g, IFN_GOMP_SIMT_VOTE_ANY)
	      || gimple_call_internal_p (g, IFN_GOMP_SIMT_XCHG_BFLY)
	      || gimple_call_internal_p (g, IFN_GOMP_SIMT_XCHG_IDX)))
	return false;
    }

  return true;
}

/* Create a duplicate of the basic block BB.  NOTE: This does not
   preserve SSA form.  */

static basic_block
gimple_duplicate_bb (basic_block bb, copy_bb_data *id)
{
  basic_block new_bb;
  gimple_stmt_iterator gsi_tgt;

  new_bb = create_empty_bb (EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb);

  /* Copy the PHI nodes.  We ignore PHI node arguments here because
     the incoming edges have not been setup yet.  */
  for (gphi_iterator gpi = gsi_start_phis (bb);
       !gsi_end_p (gpi);
       gsi_next (&gpi))
    {
      gphi *phi, *copy;
      phi = gpi.phi ();
      copy = create_phi_node (NULL_TREE, new_bb);
      create_new_def_for (gimple_phi_result (phi), copy,
			  gimple_phi_result_ptr (copy));
      gimple_set_uid (copy, gimple_uid (phi));
    }

  gsi_tgt = gsi_start_bb (new_bb);
  for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
       !gsi_end_p (gsi);
       gsi_next (&gsi))
    {
      def_operand_p def_p;
      ssa_op_iter op_iter;
      tree lhs;
      gimple *stmt, *copy;

      stmt = gsi_stmt (gsi);
      if (gimple_code (stmt) == GIMPLE_LABEL)
	continue;

      /* Don't duplicate label debug stmts.  */
      if (gimple_debug_bind_p (stmt)
	  && TREE_CODE (gimple_debug_bind_get_var (stmt))
	     == LABEL_DECL)
	continue;

      /* Create a new copy of STMT and duplicate STMT's virtual
	 operands.  */
      copy = gimple_copy (stmt);
      gsi_insert_after (&gsi_tgt, copy, GSI_NEW_STMT);

      maybe_duplicate_eh_stmt (copy, stmt);
      gimple_duplicate_stmt_histograms (cfun, copy, cfun, stmt);

      /* When copying around a stmt writing into a local non-user
	 aggregate, make sure it won't share stack slot with other
	 vars.  */
      lhs = gimple_get_lhs (stmt);
      if (lhs && TREE_CODE (lhs) != SSA_NAME)
	{
	  tree base = get_base_address (lhs);
	  if (base
	      && (VAR_P (base) || TREE_CODE (base) == RESULT_DECL)
	      && DECL_IGNORED_P (base)
	      && !TREE_STATIC (base)
	      && !DECL_EXTERNAL (base)
	      && (!VAR_P (base) || !DECL_HAS_VALUE_EXPR_P (base)))
	    DECL_NONSHAREABLE (base) = 1;
	}
 
      /* If requested remap dependence info of cliques brought in
         via inlining.  */
      if (id)
	for (unsigned i = 0; i < gimple_num_ops (copy); ++i)
	  {
	    tree op = gimple_op (copy, i);
	    if (!op)
	      continue;
	    if (TREE_CODE (op) == ADDR_EXPR
		|| TREE_CODE (op) == WITH_SIZE_EXPR)
	      op = TREE_OPERAND (op, 0);
	    while (handled_component_p (op))
	      op = TREE_OPERAND (op, 0);
	    if ((TREE_CODE (op) == MEM_REF
		 || TREE_CODE (op) == TARGET_MEM_REF)
		&& MR_DEPENDENCE_CLIQUE (op) > 1
		&& MR_DEPENDENCE_CLIQUE (op) != bb->loop_father->owned_clique)
	      {
		if (!id->dependence_map)
		  id->dependence_map = new hash_map<dependence_hash,
						    unsigned short>;
		bool existed;
		unsigned short &newc = id->dependence_map->get_or_insert
		    (MR_DEPENDENCE_CLIQUE (op), &existed);
		if (!existed)
		  {
		    gcc_assert (MR_DEPENDENCE_CLIQUE (op) <= cfun->last_clique);
		    newc = ++cfun->last_clique;
		  }
		MR_DEPENDENCE_CLIQUE (op) = newc;
	      }
	  }

      /* Create new names for all the definitions created by COPY and
	 add replacement mappings for each new name.  */
      FOR_EACH_SSA_DEF_OPERAND (def_p, copy, op_iter, SSA_OP_ALL_DEFS)
	create_new_def_for (DEF_FROM_PTR (def_p), copy, def_p);
    }

  return new_bb;
}

/* Adds phi node arguments for edge E_COPY after basic block duplication.  */

static void
add_phi_args_after_copy_edge (edge e_copy)
{
  basic_block bb, bb_copy = e_copy->src, dest;
  edge e;
  edge_iterator ei;
  gphi *phi, *phi_copy;
  tree def;
  gphi_iterator psi, psi_copy;

  if (gimple_seq_empty_p (phi_nodes (e_copy->dest)))
    return;

  bb = bb_copy->flags & BB_DUPLICATED ? get_bb_original (bb_copy) : bb_copy;

  if (e_copy->dest->flags & BB_DUPLICATED)
    dest = get_bb_original (e_copy->dest);
  else
    dest = e_copy->dest;

  e = find_edge (bb, dest);
  if (!e)
    {
      /* During loop unrolling the target of the latch edge is copied.
	 In this case we are not looking for edge to dest, but to
	 duplicated block whose original was dest.  */
      FOR_EACH_EDGE (e, ei, bb->succs)
	{
	  if ((e->dest->flags & BB_DUPLICATED)
	      && get_bb_original (e->dest) == dest)
	    break;
	}

      gcc_assert (e != NULL);
    }

  for (psi = gsi_start_phis (e->dest),
       psi_copy = gsi_start_phis (e_copy->dest);
       !gsi_end_p (psi);
       gsi_next (&psi), gsi_next (&psi_copy))
    {
      phi = psi.phi ();
      phi_copy = psi_copy.phi ();
      def = PHI_ARG_DEF_FROM_EDGE (phi, e);
      add_phi_arg (phi_copy, def, e_copy,
		   gimple_phi_arg_location_from_edge (phi, e));
    }
}


/* Basic block BB_COPY was created by code duplication.  Add phi node
   arguments for edges going out of BB_COPY.  The blocks that were
   duplicated have BB_DUPLICATED set.  */

void
add_phi_args_after_copy_bb (basic_block bb_copy)
{
  edge e_copy;
  edge_iterator ei;

  FOR_EACH_EDGE (e_copy, ei, bb_copy->succs)
    {
      add_phi_args_after_copy_edge (e_copy);
    }
}

/* Blocks in REGION_COPY array of length N_REGION were created by
   duplication of basic blocks.  Add phi node arguments for edges
   going from these blocks.  If E_COPY is not NULL, also add
   phi node arguments for its destination.*/

void
add_phi_args_after_copy (basic_block *region_copy, unsigned n_region,
			 edge e_copy)
{
  unsigned i;

  for (i = 0; i < n_region; i++)
    region_copy[i]->flags |= BB_DUPLICATED;

  for (i = 0; i < n_region; i++)
    add_phi_args_after_copy_bb (region_copy[i]);
  if (e_copy)
    add_phi_args_after_copy_edge (e_copy);

  for (i = 0; i < n_region; i++)
    region_copy[i]->flags &= ~BB_DUPLICATED;
}

/* Duplicates a REGION (set of N_REGION basic blocks) with just a single
   important exit edge EXIT.  By important we mean that no SSA name defined
   inside region is live over the other exit edges of the region.  All entry
   edges to the region must go to ENTRY->dest.  The edge ENTRY is redirected
   to the duplicate of the region.  Dominance and loop information is
   updated if UPDATE_DOMINANCE is true, but not the SSA web.  If
   UPDATE_DOMINANCE is false then we assume that the caller will update the
   dominance information after calling this function.  The new basic
   blocks are stored to REGION_COPY in the same order as they had in REGION,
   provided that REGION_COPY is not NULL.
   The function returns false if it is unable to copy the region,
   true otherwise.  */

bool
gimple_duplicate_sese_region (edge entry, edge exit,
			    basic_block *region, unsigned n_region,
			    basic_block *region_copy,
			    bool update_dominance)
{
  unsigned i;
  bool free_region_copy = false, copying_header = false;
  class loop *loop = entry->dest->loop_father;
  edge exit_copy;
  edge redirected;
  profile_count total_count = profile_count::uninitialized ();
  profile_count entry_count = profile_count::uninitialized ();

  if (!can_copy_bbs_p (region, n_region))
    return false;

  /* Some sanity checking.  Note that we do not check for all possible
     missuses of the functions.  I.e. if you ask to copy something weird,
     it will work, but the state of structures probably will not be
     correct.  */
  for (i = 0; i < n_region; i++)
    {
      /* We do not handle subloops, i.e. all the blocks must belong to the
	 same loop.  */
      if (region[i]->loop_father != loop)
	return false;

      if (region[i] != entry->dest
	  && region[i] == loop->header)
	return false;
    }

  /* In case the function is used for loop header copying (which is the primary
     use), ensure that EXIT and its copy will be new latch and entry edges.  */
  if (loop->header == entry->dest)
    {
      copying_header = true;

      if (!dominated_by_p (CDI_DOMINATORS, loop->latch, exit->src))
	return false;

      for (i = 0; i < n_region; i++)
	if (region[i] != exit->src
	    && dominated_by_p (CDI_DOMINATORS, region[i], exit->src))
	  return false;
    }

  initialize_original_copy_tables ();

  if (copying_header)
    set_loop_copy (loop, loop_outer (loop));
  else
    set_loop_copy (loop, loop);

  if (!region_copy)
    {
      region_copy = XNEWVEC (basic_block, n_region);
      free_region_copy = true;
    }

  /* Record blocks outside the region that are dominated by something
     inside.  */
  auto_vec<basic_block> doms;
  if (update_dominance)
    {
      doms = get_dominated_by_region (CDI_DOMINATORS, region, n_region);
    }

  if (entry->dest->count.initialized_p ())
    {
      total_count = entry->dest->count;
      entry_count = entry->count ();
      /* Fix up corner cases, to avoid division by zero or creation of negative
	 frequencies.  */
      if (entry_count > total_count)
	entry_count = total_count;
    }

  copy_bbs (region, n_region, region_copy, &exit, 1, &exit_copy, loop,
	    split_edge_bb_loc (entry), update_dominance);
  if (total_count.initialized_p () && entry_count.initialized_p ())
    {
      scale_bbs_frequencies_profile_count (region, n_region,
				           total_count - entry_count,
				           total_count);
      scale_bbs_frequencies_profile_count (region_copy, n_region, entry_count,
				           total_count);
    }

  if (copying_header)
    {
      loop->header = exit->dest;
      loop->latch = exit->src;
    }

  /* Redirect the entry and add the phi node arguments.  */
  redirected = redirect_edge_and_branch (entry, get_bb_copy (entry->dest));
  gcc_assert (redirected != NULL);
  flush_pending_stmts (entry);

  /* Concerning updating of dominators:  We must recount dominators
     for entry block and its copy.  Anything that is outside of the
     region, but was dominated by something inside needs recounting as
     well.  */
  if (update_dominance)
    {
      set_immediate_dominator (CDI_DOMINATORS, entry->dest, entry->src);
      doms.safe_push (get_bb_original (entry->dest));
      iterate_fix_dominators (CDI_DOMINATORS, doms, false);
    }

  /* Add the other PHI node arguments.  */
  add_phi_args_after_copy (region_copy, n_region, NULL);

  if (free_region_copy)
    free (region_copy);

  free_original_copy_tables ();
  return true;
}

/* Checks if BB is part of the region defined by N_REGION BBS.  */
static bool 
bb_part_of_region_p (basic_block bb, basic_block* bbs, unsigned n_region)
{
  unsigned int n;

  for (n = 0; n < n_region; n++)
    {
     if (bb == bbs[n])
       return true;
    }
  return false;
}

/* Duplicates REGION consisting of N_REGION blocks.  The new blocks
   are stored to REGION_COPY in the same order in that they appear
   in REGION, if REGION_COPY is not NULL.  ENTRY is the entry to
   the region, EXIT an exit from it.  The condition guarding EXIT
   is moved to ENTRY.  Returns true if duplication succeeds, false
   otherwise.

   For example,

   some_code;
   if (cond)
     A;
   else
     B;

   is transformed to

   if (cond)
     {
       some_code;
       A;
     }
   else
     {
       some_code;
       B;
     }
*/

bool
gimple_duplicate_sese_tail (edge entry, edge exit,
			  basic_block *region, unsigned n_region,
			  basic_block *region_copy)
{
  unsigned i;
  bool free_region_copy = false;
  class loop *loop = exit->dest->loop_father;
  class loop *orig_loop = entry->dest->loop_father;
  basic_block switch_bb, entry_bb, nentry_bb;
  profile_count total_count = profile_count::uninitialized (),
		exit_count = profile_count::uninitialized ();
  edge exits[2], nexits[2], e;
  gimple_stmt_iterator gsi;
  gimple *cond_stmt;
  edge sorig, snew;
  basic_block exit_bb;
  gphi_iterator psi;
  gphi *phi;
  tree def;
  class loop *target, *aloop, *cloop;

  gcc_assert (EDGE_COUNT (exit->src->succs) == 2);
  exits[0] = exit;
  exits[1] = EDGE_SUCC (exit->src, EDGE_SUCC (exit->src, 0) == exit);

  if (!can_copy_bbs_p (region, n_region))
    return false;

  initialize_original_copy_tables ();
  set_loop_copy (orig_loop, loop);

  target= loop;
  for (aloop = orig_loop->inner; aloop; aloop = aloop->next)
    {
      if (bb_part_of_region_p (aloop->header, region, n_region))
	{
	  cloop = duplicate_loop (aloop, target);
	  duplicate_subloops (aloop, cloop);
	}
    }

  if (!region_copy)
    {
      region_copy = XNEWVEC (basic_block, n_region);
      free_region_copy = true;
    }

  gcc_assert (!need_ssa_update_p (cfun));

  /* Record blocks outside the region that are dominated by something
     inside.  */
  auto_vec<basic_block> doms = get_dominated_by_region (CDI_DOMINATORS, region,
							n_region);

  total_count = exit->src->count;
  exit_count = exit->count ();
  /* Fix up corner cases, to avoid division by zero or creation of negative
     frequencies.  */
  if (exit_count > total_count)
    exit_count = total_count;

  copy_bbs (region, n_region, region_copy, exits, 2, nexits, orig_loop,
	    split_edge_bb_loc (exit), true);
  if (total_count.initialized_p () && exit_count.initialized_p ())
    {
      scale_bbs_frequencies_profile_count (region, n_region,
				           total_count - exit_count,
				           total_count);
      scale_bbs_frequencies_profile_count (region_copy, n_region, exit_count,
				           total_count);
    }

  /* Create the switch block, and put the exit condition to it.  */
  entry_bb = entry->dest;
  nentry_bb = get_bb_copy (entry_bb);
  if (!last_stmt (entry->src)
      || !stmt_ends_bb_p (last_stmt (entry->src)))
    switch_bb = entry->src;
  else
    switch_bb = split_edge (entry);
  set_immediate_dominator (CDI_DOMINATORS, nentry_bb, switch_bb);

  gsi = gsi_last_bb (switch_bb);
  cond_stmt = last_stmt (exit->src);
  gcc_assert (gimple_code (cond_stmt) == GIMPLE_COND);
  cond_stmt = gimple_copy (cond_stmt);

  gsi_insert_after (&gsi, cond_stmt, GSI_NEW_STMT);

  sorig = single_succ_edge (switch_bb);
  sorig->flags = exits[1]->flags;
  sorig->probability = exits[1]->probability;
  snew = make_edge (switch_bb, nentry_bb, exits[0]->flags);
  snew->probability = exits[0]->probability;
  

  /* Register the new edge from SWITCH_BB in loop exit lists.  */
  rescan_loop_exit (snew, true, false);

  /* Add the PHI node arguments.  */
  add_phi_args_after_copy (region_copy, n_region, snew);

  /* Get rid of now superfluous conditions and associated edges (and phi node
     arguments).  */
  exit_bb = exit->dest;

  e = redirect_edge_and_branch (exits[0], exits[1]->dest);
  PENDING_STMT (e) = NULL;

  /* The latch of ORIG_LOOP was copied, and so was the backedge 
     to the original header.  We redirect this backedge to EXIT_BB.  */
  for (i = 0; i < n_region; i++)
    if (get_bb_original (region_copy[i]) == orig_loop->latch)
      {
	gcc_assert (single_succ_edge (region_copy[i]));
	e = redirect_edge_and_branch (single_succ_edge (region_copy[i]), exit_bb);
	PENDING_STMT (e) = NULL;
	for (psi = gsi_start_phis (exit_bb);
	     !gsi_end_p (psi);
	     gsi_next (&psi))
	  {
	    phi = psi.phi ();
	    def = PHI_ARG_DEF (phi, nexits[0]->dest_idx);
	    add_phi_arg (phi, def, e, gimple_phi_arg_location_from_edge (phi, e));
	  }
      }
  e = redirect_edge_and_branch (nexits[1], nexits[0]->dest);
  PENDING_STMT (e) = NULL;
  
  /* Anything that is outside of the region, but was dominated by something
     inside needs to update dominance info.  */
  iterate_fix_dominators (CDI_DOMINATORS, doms, false);

  if (free_region_copy)
    free (region_copy);

  free_original_copy_tables ();
  return true;
}

/* Add all the blocks dominated by ENTRY to the array BBS_P.  Stop
   adding blocks when the dominator traversal reaches EXIT.  This
   function silently assumes that ENTRY strictly dominates EXIT.  */

void
gather_blocks_in_sese_region (basic_block entry, basic_block exit,
			      vec<basic_block> *bbs_p)
{
  basic_block son;

  for (son = first_dom_son (CDI_DOMINATORS, entry);
       son;
       son = next_dom_son (CDI_DOMINATORS, son))
    {
      bbs_p->safe_push (son);
      if (son != exit)
	gather_blocks_in_sese_region (son, exit, bbs_p);
    }
}

/* Replaces *TP with a duplicate (belonging to function TO_CONTEXT).
   The duplicates are recorded in VARS_MAP.  */

static void
replace_by_duplicate_decl (tree *tp, hash_map<tree, tree> *vars_map,
			   tree to_context)
{
  tree t = *tp, new_t;
  struct function *f = DECL_STRUCT_FUNCTION (to_context);

  if (DECL_CONTEXT (t) == to_context)
    return;

  bool existed;
  tree &loc = vars_map->get_or_insert (t, &existed);

  if (!existed)
    {
      if (SSA_VAR_P (t))
	{
	  new_t = copy_var_decl (t, DECL_NAME (t), TREE_TYPE (t));
	  add_local_decl (f, new_t);
	}
      else
	{
	  gcc_assert (TREE_CODE (t) == CONST_DECL);
	  new_t = copy_node (t);
	}
      DECL_CONTEXT (new_t) = to_context;

      loc = new_t;
    }
  else
    new_t = loc;

  *tp = new_t;
}


/* Creates an ssa name in TO_CONTEXT equivalent to NAME.
   VARS_MAP maps old ssa names and var_decls to the new ones.  */

static tree
replace_ssa_name (tree name, hash_map<tree, tree> *vars_map,
		  tree to_context)
{
  tree new_name;

  gcc_assert (!virtual_operand_p (name));

  tree *loc = vars_map->get (name);

  if (!loc)
    {
      tree decl = SSA_NAME_VAR (name);
      if (decl)
	{
	  gcc_assert (!SSA_NAME_IS_DEFAULT_DEF (name));
	  replace_by_duplicate_decl (&decl, vars_map, to_context);
	  new_name = make_ssa_name_fn (DECL_STRUCT_FUNCTION (to_context),
				       decl, SSA_NAME_DEF_STMT (name));
	}
      else
	new_name = copy_ssa_name_fn (DECL_STRUCT_FUNCTION (to_context),
				     name, SSA_NAME_DEF_STMT (name));

      /* Now that we've used the def stmt to define new_name, make sure it
	 doesn't define name anymore.  */
      SSA_NAME_DEF_STMT (name) = NULL;

      vars_map->put (name, new_name);
    }
  else
    new_name = *loc;

  return new_name;
}

struct move_stmt_d
{
  tree orig_block;
  tree new_block;
  tree from_context;
  tree to_context;
  hash_map<tree, tree> *vars_map;
  htab_t new_label_map;
  hash_map<void *, void *> *eh_map;
  bool remap_decls_p;
};

/* Helper for move_block_to_fn.  Set TREE_BLOCK in every expression
   contained in *TP if it has been ORIG_BLOCK previously and change the
   DECL_CONTEXT of every local variable referenced in *TP.  */

static tree
move_stmt_op (tree *tp, int *walk_subtrees, void *data)
{
  struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
  struct move_stmt_d *p = (struct move_stmt_d *) wi->info;
  tree t = *tp;

  if (EXPR_P (t))
    {
      tree block = TREE_BLOCK (t);
      if (block == NULL_TREE)
	;
      else if (block == p->orig_block
	       || p->orig_block == NULL_TREE)
	{
	  /* tree_node_can_be_shared says we can share invariant
	     addresses but unshare_expr copies them anyways.  Make sure
	     to unshare before adjusting the block in place - we do not
	     always see a copy here.  */
	  if (TREE_CODE (t) == ADDR_EXPR
	      && is_gimple_min_invariant (t))
	    *tp = t = unshare_expr (t);
	  TREE_SET_BLOCK (t, p->new_block);
	}
      else if (flag_checking)
	{
	  while (block && TREE_CODE (block) == BLOCK && block != p->orig_block)
	    block = BLOCK_SUPERCONTEXT (block);
	  gcc_assert (block == p->orig_block);
	}
    }
  else if (DECL_P (t) || TREE_CODE (t) == SSA_NAME)
    {
      if (TREE_CODE (t) == SSA_NAME)
	*tp = replace_ssa_name (t, p->vars_map, p->to_context);
      else if (TREE_CODE (t) == PARM_DECL
	       && gimple_in_ssa_p (cfun))
	*tp = *(p->vars_map->get (t));
      else if (TREE_CODE (t) == LABEL_DECL)
	{
	  if (p->new_label_map)
	    {
	      struct tree_map in, *out;
	      in.base.from = t;
	      out = (struct tree_map *)
		htab_find_with_hash (p->new_label_map, &in, DECL_UID (t));
	      if (out)
		*tp = t = out->to;
	    }

	  /* For FORCED_LABELs we can end up with references from other
	     functions if some SESE regions are outlined.  It is UB to
	     jump in between them, but they could be used just for printing
	     addresses etc.  In that case, DECL_CONTEXT on the label should
	     be the function containing the glabel stmt with that LABEL_DECL,
	     rather than whatever function a reference to the label was seen
	     last time.  */
	  if (!FORCED_LABEL (t) && !DECL_NONLOCAL (t))
	    DECL_CONTEXT (t) = p->to_context;
	}
      else if (p->remap_decls_p)
	{
	  /* Replace T with its duplicate.  T should no longer appear in the
	     parent function, so this looks wasteful; however, it may appear
	     in referenced_vars, and more importantly, as virtual operands of
	     statements, and in alias lists of other variables.  It would be
	     quite difficult to expunge it from all those places.  ??? It might
	     suffice to do this for addressable variables.  */
	  if ((VAR_P (t) && !is_global_var (t))
	      || TREE_CODE (t) == CONST_DECL)
	    replace_by_duplicate_decl (tp, p->vars_map, p->to_context);
	}
      *walk_subtrees = 0;
    }
  else if (TYPE_P (t))
    *walk_subtrees = 0;

  return NULL_TREE;
}

/* Helper for move_stmt_r.  Given an EH region number for the source
   function, map that to the duplicate EH regio number in the dest.  */

static int
move_stmt_eh_region_nr (int old_nr, struct move_stmt_d *p)
{
  eh_region old_r, new_r;

  old_r = get_eh_region_from_number (old_nr);
  new_r = static_cast<eh_region> (*p->eh_map->get (old_r));

  return new_r->index;
}

/* Similar, but operate on INTEGER_CSTs.  */

static tree
move_stmt_eh_region_tree_nr (tree old_t_nr, struct move_stmt_d *p)
{
  int old_nr, new_nr;

  old_nr = tree_to_shwi (old_t_nr);
  new_nr = move_stmt_eh_region_nr (old_nr, p);

  return build_int_cst (integer_type_node, new_nr);
}

/* Like move_stmt_op, but for gimple statements.

   Helper for move_block_to_fn.  Set GIMPLE_BLOCK in every expression
   contained in the current statement in *GSI_P and change the
   DECL_CONTEXT of every local variable referenced in the current
   statement.  */

static tree
move_stmt_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
	     struct walk_stmt_info *wi)
{
  struct move_stmt_d *p = (struct move_stmt_d *) wi->info;
  gimple *stmt = gsi_stmt (*gsi_p);
  tree block = gimple_block (stmt);

  if (block == p->orig_block
      || (p->orig_block == NULL_TREE
	  && block != NULL_TREE))
    gimple_set_block (stmt, p->new_block);

  switch (gimple_code (stmt))
    {
    case GIMPLE_CALL:
      /* Remap the region numbers for __builtin_eh_{pointer,filter}.  */
      {
	tree r, fndecl = gimple_call_fndecl (stmt);
	if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
	  switch (DECL_FUNCTION_CODE (fndecl))
	    {
	    case BUILT_IN_EH_COPY_VALUES:
	      r = gimple_call_arg (stmt, 1);
	      r = move_stmt_eh_region_tree_nr (r, p);
	      gimple_call_set_arg (stmt, 1, r);
	      /* FALLTHRU */

	    case BUILT_IN_EH_POINTER:
	    case BUILT_IN_EH_FILTER:
	      r = gimple_call_arg (stmt, 0);
	      r = move_stmt_eh_region_tree_nr (r, p);
	      gimple_call_set_arg (stmt, 0, r);
	      break;

	    default:
	      break;
	    }
      }
      break;

    case GIMPLE_RESX:
      {
	gresx *resx_stmt = as_a <gresx *> (stmt);
	int r = gimple_resx_region (resx_stmt);
	r = move_stmt_eh_region_nr (r, p);
	gimple_resx_set_region (resx_stmt, r);
      }
      break;

    case GIMPLE_EH_DISPATCH:
      {
	geh_dispatch *eh_dispatch_stmt = as_a <geh_dispatch *> (stmt);
	int r = gimple_eh_dispatch_region (eh_dispatch_stmt);
	r = move_stmt_eh_region_nr (r, p);
	gimple_eh_dispatch_set_region (eh_dispatch_stmt, r);
      }
      break;

    case GIMPLE_OMP_RETURN:
    case GIMPLE_OMP_CONTINUE:
      break;

    case GIMPLE_LABEL:
      {
	/* For FORCED_LABEL, move_stmt_op doesn't adjust DECL_CONTEXT,
	   so that such labels can be referenced from other regions.
	   Make sure to update it when seeing a GIMPLE_LABEL though,
	   that is the owner of the label.  */
	walk_gimple_op (stmt, move_stmt_op, wi);
	*handled_ops_p = true;
	tree label = gimple_label_label (as_a <glabel *> (stmt));
	if (FORCED_LABEL (label) || DECL_NONLOCAL (label))
	  DECL_CONTEXT (label) = p->to_context;
      }
      break;

    default:
      if (is_gimple_omp (stmt))
	{
	  /* Do not remap variables inside OMP directives.  Variables
	     referenced in clauses and directive header belong to the
	     parent function and should not be moved into the child
	     function.  */
	  bool save_remap_decls_p = p->remap_decls_p;
	  p->remap_decls_p = false;
	  *handled_ops_p = true;

	  walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), move_stmt_r,
			       move_stmt_op, wi);

	  p->remap_decls_p = save_remap_decls_p;
	}
      break;
    }

  return NULL_TREE;
}

/* Move basic block BB from function CFUN to function DEST_FN.  The
   block is moved out of the original linked list and placed after
   block AFTER in the new list.  Also, the block is removed from the
   original array of blocks and placed in DEST_FN's array of blocks.
   If UPDATE_EDGE_COUNT_P is true, the edge counts on both CFGs is
   updated to reflect the moved edges.

   The local variables are remapped to new instances, VARS_MAP is used
   to record the mapping.  */

static void
move_block_to_fn (struct function *dest_cfun, basic_block bb,
		  basic_block after, bool update_edge_count_p,
		  struct move_stmt_d *d)
{
  struct control_flow_graph *cfg;
  edge_iterator ei;
  edge e;
  gimple_stmt_iterator si;
  unsigned old_len;

  /* Remove BB from dominance structures.  */
  delete_from_dominance_info (CDI_DOMINATORS, bb);

  /* Move BB from its current loop to the copy in the new function.  */
  if (current_loops)
    {
      class loop *new_loop = (class loop *)bb->loop_father->aux;
      if (new_loop)
	bb->loop_father = new_loop;
    }

  /* Link BB to the new linked list.  */
  move_block_after (bb, after);

  /* Update the edge count in the corresponding flowgraphs.  */
  if (update_edge_count_p)
    FOR_EACH_EDGE (e, ei, bb->succs)
      {
	cfun->cfg->x_n_edges--;
	dest_cfun->cfg->x_n_edges++;
      }

  /* Remove BB from the original basic block array.  */
  (*cfun->cfg->x_basic_block_info)[bb->index] = NULL;
  cfun->cfg->x_n_basic_blocks--;

  /* Grow DEST_CFUN's basic block array if needed.  */
  cfg = dest_cfun->cfg;
  cfg->x_n_basic_blocks++;
  if (bb->index >= cfg->x_last_basic_block)
    cfg->x_last_basic_block = bb->index + 1;

  old_len = vec_safe_length (cfg->x_basic_block_info);
  if ((unsigned) cfg->x_last_basic_block >= old_len)
    vec_safe_grow_cleared (cfg->x_basic_block_info,
			   cfg->x_last_basic_block + 1);

  (*cfg->x_basic_block_info)[bb->index] = bb;

  /* Remap the variables in phi nodes.  */
  for (gphi_iterator psi = gsi_start_phis (bb);
       !gsi_end_p (psi); )
    {
      gphi *phi = psi.phi ();
      use_operand_p use;
      tree op = PHI_RESULT (phi);
      ssa_op_iter oi;
      unsigned i;

      if (virtual_operand_p (op))
	{
	  /* Remove the phi nodes for virtual operands (alias analysis will be
	     run for the new function, anyway).  But replace all uses that
	     might be outside of the region we move.  */
	  use_operand_p use_p;
	  imm_use_iterator iter;
	  gimple *use_stmt;
	  FOR_EACH_IMM_USE_STMT (use_stmt, iter, op)
	    FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
	      SET_USE (use_p, SSA_NAME_VAR (op));
          remove_phi_node (&psi, true);
	  continue;
	}

      SET_PHI_RESULT (phi,
		      replace_ssa_name (op, d->vars_map, dest_cfun->decl));
      FOR_EACH_PHI_ARG (use, phi, oi, SSA_OP_USE)
	{
	  op = USE_FROM_PTR (use);
	  if (TREE_CODE (op) == SSA_NAME)
	    SET_USE (use, replace_ssa_name (op, d->vars_map, dest_cfun->decl));
	}

      for (i = 0; i < EDGE_COUNT (bb->preds); i++)
	{
	  location_t locus = gimple_phi_arg_location (phi, i);
	  tree block = LOCATION_BLOCK (locus);

	  if (locus == UNKNOWN_LOCATION)
	    continue;
	  if (d->orig_block == NULL_TREE || block == d->orig_block)
	    {
	      locus = set_block (locus, d->new_block);
	      gimple_phi_arg_set_location (phi, i, locus);
	    }
	}

      gsi_next (&psi);
    }

  for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
    {
      gimple *stmt = gsi_stmt (si);
      struct walk_stmt_info wi;

      memset (&wi, 0, sizeof (wi));
      wi.info = d;
      walk_gimple_stmt (&si, move_stmt_r, move_stmt_op, &wi);

      if (glabel *label_stmt = dyn_cast <glabel *> (stmt))
	{
	  tree label = gimple_label_label (label_stmt);
	  int uid = LABEL_DECL_UID (label);

	  gcc_assert (uid > -1);

	  old_len = vec_safe_length (cfg->x_label_to_block_map);
	  if (old_len <= (unsigned) uid)
	    vec_safe_grow_cleared (cfg->x_label_to_block_map, uid + 1);

	  (*cfg->x_label_to_block_map)[uid] = bb;
	  (*cfun->cfg->x_label_to_block_map)[uid] = NULL;

	  gcc_assert (DECL_CONTEXT (label) == dest_cfun->decl);

	  if (uid >= dest_cfun->cfg->last_label_uid)
	    dest_cfun->cfg->last_label_uid = uid + 1;
	}

      maybe_duplicate_eh_stmt_fn (dest_cfun, stmt, cfun, stmt, d->eh_map, 0);
      remove_stmt_from_eh_lp_fn (cfun, stmt);

      gimple_duplicate_stmt_histograms (dest_cfun, stmt, cfun, stmt);
      gimple_remove_stmt_histograms (cfun, stmt);

      /* We cannot leave any operands allocated from the operand caches of
	 the current function.  */
      free_stmt_operands (cfun, stmt);
      push_cfun (dest_cfun);
      update_stmt (stmt);
      if (is_gimple_call (stmt))
	notice_special_calls (as_a <gcall *> (stmt));
      pop_cfun ();
    }

  FOR_EACH_EDGE (e, ei, bb->succs)
    if (e->goto_locus != UNKNOWN_LOCATION)
      {
	tree block = LOCATION_BLOCK (e->goto_locus);
	if (d->orig_block == NULL_TREE
	    || block == d->orig_block)
	  e->goto_locus = set_block (e->goto_locus, d->new_block);
      }
}

/* Examine the statements in BB (which is in SRC_CFUN); find and return
   the outermost EH region.  Use REGION as the incoming base EH region.
   If there is no single outermost region, return NULL and set *ALL to
   true.  */

static eh_region
find_outermost_region_in_block (struct function *src_cfun,
				basic_block bb, eh_region region,
				bool *all)
{
  gimple_stmt_iterator si;

  for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
    {
      gimple *stmt = gsi_stmt (si);
      eh_region stmt_region;
      int lp_nr;

      lp_nr = lookup_stmt_eh_lp_fn (src_cfun, stmt);
      stmt_region = get_eh_region_from_lp_number_fn (src_cfun, lp_nr);
      if (stmt_region)
	{
	  if (region == NULL)
	    region = stmt_region;
	  else if (stmt_region != region)
	    {
	      region = eh_region_outermost (src_cfun, stmt_region, region);
	      if (region == NULL)
		{
		  *all = true;
		  return NULL;
		}
	    }
	}
    }

  return region;
}

static tree
new_label_mapper (tree decl, void *data)
{
  htab_t hash = (htab_t) data;
  struct tree_map *m;
  void **slot;

  gcc_assert (TREE_CODE (decl) == LABEL_DECL);

  m = XNEW (struct tree_map);
  m->hash = DECL_UID (decl);
  m->base.from = decl;
  m->to = create_artificial_label (UNKNOWN_LOCATION);
  LABEL_DECL_UID (m->to) = LABEL_DECL_UID (decl);
  if (LABEL_DECL_UID (m->to) >= cfun->cfg->last_label_uid)
    cfun->cfg->last_label_uid = LABEL_DECL_UID (m->to) + 1;

  slot = htab_find_slot_with_hash (hash, m, m->hash, INSERT);
  gcc_assert (*slot == NULL);

  *slot = m;

  return m->to;
}

/* Tree walker to replace the decls used inside value expressions by
   duplicates.  */

static tree
replace_block_vars_by_duplicates_1 (tree *tp, int *walk_subtrees, void *data)
{
  struct replace_decls_d *rd = (struct replace_decls_d *)data;

  switch (TREE_CODE (*tp))
    {
    case VAR_DECL:
    case PARM_DECL:
    case RESULT_DECL:
      replace_by_duplicate_decl (tp, rd->vars_map, rd->to_context);
      break;
    default:
      break;
    }

  if (IS_TYPE_OR_DECL_P (*tp))
    *walk_subtrees = false;

  return NULL;
}

/* Change DECL_CONTEXT of all BLOCK_VARS in block, including
   subblocks.  */

static void
replace_block_vars_by_duplicates (tree block, hash_map<tree, tree> *vars_map,
				  tree to_context)
{
  tree *tp, t;

  for (tp = &BLOCK_VARS (block); *tp; tp = &DECL_CHAIN (*tp))
    {
      t = *tp;
      if (!VAR_P (t) && TREE_CODE (t) != CONST_DECL)
	continue;
      replace_by_duplicate_decl (&t, vars_map, to_context);
      if (t != *tp)
	{
	  if (VAR_P (*tp) && DECL_HAS_VALUE_EXPR_P (*tp))
	    {
	      tree x = DECL_VALUE_EXPR (*tp);
	      struct replace_decls_d rd = { vars_map, to_context };
	      unshare_expr (x);
	      walk_tree (&x, replace_block_vars_by_duplicates_1, &rd, NULL);
	      SET_DECL_VALUE_EXPR (t, x);
	      DECL_HAS_VALUE_EXPR_P (t) = 1;
	    }
	  DECL_CHAIN (t) = DECL_CHAIN (*tp);
	  *tp = t;
	}
    }

  for (block = BLOCK_SUBBLOCKS (block); block; block = BLOCK_CHAIN (block))
    replace_block_vars_by_duplicates (block, vars_map, to_context);
}

/* Fixup the loop arrays and numbers after moving LOOP and its subloops
   from FN1 to FN2.  */

static void
fixup_loop_arrays_after_move (struct function *fn1, struct function *fn2,
			      class loop *loop)
{
  /* Discard it from the old loop array.  */
  (*get_loops (fn1))[loop->num] = NULL;

  /* Place it in the new loop array, assigning it a new number.  */
  loop->num = number_of_loops (fn2);
  vec_safe_push (loops_for_fn (fn2)->larray, loop);

  /* Recurse to children.  */
  for (loop = loop->inner; loop; loop = loop->next)
    fixup_loop_arrays_after_move (fn1, fn2, loop);
}

/* Verify that the blocks in BBS_P are a single-entry, single-exit region
   delimited by ENTRY_BB and EXIT_BB, possibly containing noreturn blocks.  */

DEBUG_FUNCTION void
verify_sese (basic_block entry, basic_block exit, vec<basic_block> *bbs_p)
{
  basic_block bb;
  edge_iterator ei;
  edge e;
  bitmap bbs = BITMAP_ALLOC (NULL);
  int i;

  gcc_assert (entry != NULL);
  gcc_assert (entry != exit);
  gcc_assert (bbs_p != NULL);

  gcc_assert (bbs_p->length () > 0);

  FOR_EACH_VEC_ELT (*bbs_p, i, bb)
    bitmap_set_bit (bbs, bb->index);

  gcc_assert (bitmap_bit_p (bbs, entry->index));
  gcc_assert (exit == NULL || bitmap_bit_p (bbs, exit->index));

  FOR_EACH_VEC_ELT (*bbs_p, i, bb)
    {
      if (bb == entry)
	{
	  gcc_assert (single_pred_p (entry));
	  gcc_assert (!bitmap_bit_p (bbs, single_pred (entry)->index));
	}
      else
	for (ei = ei_start (bb->preds); !ei_end_p (ei); ei_next (&ei))
	  {
	    e = ei_edge (ei);
	    gcc_assert (bitmap_bit_p (bbs, e->src->index));
	  }

      if (bb == exit)
	{
	  gcc_assert (single_succ_p (exit));
	  gcc_assert (!bitmap_bit_p (bbs, single_succ (exit)->index));
	}
      else
	for (ei = ei_start (bb->succs); !ei_end_p (ei); ei_next (&ei))
	  {
	    e = ei_edge (ei);
	    gcc_assert (bitmap_bit_p (bbs, e->dest->index));
	  }
    }

  BITMAP_FREE (bbs);
}

/* If FROM is an SSA_NAME, mark the version in bitmap DATA.  */

bool
gather_ssa_name_hash_map_from (tree const &from, tree const &, void *data)
{
  bitmap release_names = (bitmap)data;

  if (TREE_CODE (from) != SSA_NAME)
    return true;

  bitmap_set_bit (release_names, SSA_NAME_VERSION (from));
  return true;
}

/* Return LOOP_DIST_ALIAS call if present in BB.  */

static gimple *
find_loop_dist_alias (basic_block bb)
{
  gimple *g = last_stmt (bb);
  if (g == NULL || gimple_code (g) != GIMPLE_COND)
    return NULL;

  gimple_stmt_iterator gsi = gsi_for_stmt (g);
  gsi_prev (&gsi);
  if (gsi_end_p (gsi))
    return NULL;

  g = gsi_stmt (gsi);
  if (gimple_call_internal_p (g, IFN_LOOP_DIST_ALIAS))
    return g;
  return NULL;
}

/* Fold loop internal call G like IFN_LOOP_VECTORIZED/IFN_LOOP_DIST_ALIAS
   to VALUE and update any immediate uses of it's LHS.  */

void
fold_loop_internal_call (gimple *g, tree value)
{
  tree lhs = gimple_call_lhs (g);
  use_operand_p use_p;
  imm_use_iterator iter;
  gimple *use_stmt;
  gimple_stmt_iterator gsi = gsi_for_stmt (g);

  replace_call_with_value (&gsi, value);
  FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)
    {
      FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
	SET_USE (use_p, value);
      update_stmt (use_stmt);
    }
}

/* Move a single-entry, single-exit region delimited by ENTRY_BB and
   EXIT_BB to function DEST_CFUN.  The whole region is replaced by a
   single basic block in the original CFG and the new basic block is
   returned.  DEST_CFUN must not have a CFG yet.

   Note that the region need not be a pure SESE region.  Blocks inside
   the region may contain calls to abort/exit.  The only restriction
   is that ENTRY_BB should be the only entry point and it must
   dominate EXIT_BB.

   Change TREE_BLOCK of all statements in ORIG_BLOCK to the new
   functions outermost BLOCK, move all subblocks of ORIG_BLOCK
   to the new function.

   All local variables referenced in the region are assumed to be in
   the corresponding BLOCK_VARS and unexpanded variable lists
   associated with DEST_CFUN.

   TODO: investigate whether we can reuse gimple_duplicate_sese_region to
   reimplement move_sese_region_to_fn by duplicating the region rather than
   moving it.  */

basic_block
move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
		        basic_block exit_bb, tree orig_block)
{
  vec<basic_block> bbs;
  basic_block dom_entry = get_immediate_dominator (CDI_DOMINATORS, entry_bb);
  basic_block after, bb, *entry_pred, *exit_succ, abb;
  struct function *saved_cfun = cfun;
  int *entry_flag, *exit_flag;
  profile_probability *entry_prob, *exit_prob;
  unsigned i, num_entry_edges, num_exit_edges, num_nodes;
  edge e;
  edge_iterator ei;
  htab_t new_label_map;
  hash_map<void *, void *> *eh_map;
  class loop *loop = entry_bb->loop_father;
  class loop *loop0 = get_loop (saved_cfun, 0);
  struct move_stmt_d d;

  /* If ENTRY does not strictly dominate EXIT, this cannot be an SESE
     region.  */
  gcc_assert (entry_bb != exit_bb
              && (!exit_bb
		  || dominated_by_p (CDI_DOMINATORS, exit_bb, entry_bb)));

  /* Collect all the blocks in the region.  Manually add ENTRY_BB
     because it won't be added by dfs_enumerate_from.  */
  bbs.create (0);
  bbs.safe_push (entry_bb);
  gather_blocks_in_sese_region (entry_bb, exit_bb, &bbs);

  if (flag_checking)
    verify_sese (entry_bb, exit_bb, &bbs);

  /* The blocks that used to be dominated by something in BBS will now be
     dominated by the new block.  */
  auto_vec<basic_block> dom_bbs = get_dominated_by_region (CDI_DOMINATORS,
							   bbs.address (),
							   bbs.length ());

  /* Detach ENTRY_BB and EXIT_BB from CFUN->CFG.  We need to remember
     the predecessor edges to ENTRY_BB and the successor edges to
     EXIT_BB so that we can re-attach them to the new basic block that
     will replace the region.  */
  num_entry_edges = EDGE_COUNT (entry_bb->preds);
  entry_pred = XNEWVEC (basic_block, num_entry_edges);
  entry_flag = XNEWVEC (int, num_entry_edges);
  entry_prob = XNEWVEC (profile_probability, num_entry_edges);
  i = 0;
  for (ei = ei_start (entry_bb->preds); (e = ei_safe_edge (ei)) != NULL;)
    {
      entry_prob[i] = e->probability;
      entry_flag[i] = e->flags;
      entry_pred[i++] = e->src;
      remove_edge (e);
    }

  if (exit_bb)
    {
      num_exit_edges = EDGE_COUNT (exit_bb->succs);
      exit_succ = XNEWVEC (basic_block, num_exit_edges);
      exit_flag = XNEWVEC (int, num_exit_edges);
      exit_prob = XNEWVEC (profile_probability, num_exit_edges);
      i = 0;
      for (ei = ei_start (exit_bb->succs); (e = ei_safe_edge (ei)) != NULL;)
	{
	  exit_prob[i] = e->probability;
	  exit_flag[i] = e->flags;
	  exit_succ[i++] = e->dest;
	  remove_edge (e);
	}
    }
  else
    {
      num_exit_edges = 0;
      exit_succ = NULL;
      exit_flag = NULL;
      exit_prob = NULL;
    }

  /* Switch context to the child function to initialize DEST_FN's CFG.  */
  gcc_assert (dest_cfun->cfg == NULL);
  push_cfun (dest_cfun);

  init_empty_tree_cfg ();

  /* Initialize EH information for the new function.  */
  eh_map = NULL;
  new_label_map = NULL;
  if (saved_cfun->eh)
    {
      eh_region region = NULL;
      bool all = false;

      FOR_EACH_VEC_ELT (bbs, i, bb)
	{
	  region = find_outermost_region_in_block (saved_cfun, bb, region, &all);
	  if (all)
	    break;
	}

      init_eh_for_function ();
      if (region != NULL || all)
	{
	  new_label_map = htab_create (17, tree_map_hash, tree_map_eq, free);
	  eh_map = duplicate_eh_regions (saved_cfun, region, 0,
					 new_label_mapper, new_label_map);
	}
    }

  /* Initialize an empty loop tree.  */
  struct loops *loops = ggc_cleared_alloc<struct loops> ();
  init_loops_structure (dest_cfun, loops, 1);
  loops->state = LOOPS_MAY_HAVE_MULTIPLE_LATCHES;
  set_loops_for_fn (dest_cfun, loops);

  vec<loop_p, va_gc> *larray = get_loops (saved_cfun)->copy ();

  /* Move the outlined loop tree part.  */
  num_nodes = bbs.length ();
  FOR_EACH_VEC_ELT (bbs, i, bb)
    {
      if (bb->loop_father->header == bb)
	{
	  class loop *this_loop = bb->loop_father;
	  class loop *outer = loop_outer (this_loop);
	  if (outer == loop
	      /* If the SESE region contains some bbs ending with
		 a noreturn call, those are considered to belong
		 to the outermost loop in saved_cfun, rather than
		 the entry_bb's loop_father.  */
	      || outer == loop0)
	    {
	      if (outer != loop)
		num_nodes -= this_loop->num_nodes;
	      flow_loop_tree_node_remove (bb->loop_father);
	      flow_loop_tree_node_add (get_loop (dest_cfun, 0), this_loop);
	      fixup_loop_arrays_after_move (saved_cfun, cfun, this_loop);
	    }
	}
      else if (bb->loop_father == loop0 && loop0 != loop)
	num_nodes--;

      /* Remove loop exits from the outlined region.  */
      if (loops_for_fn (saved_cfun)->exits)
	FOR_EACH_EDGE (e, ei, bb->succs)
	  {
	    struct loops *l = loops_for_fn (saved_cfun);
	    loop_exit **slot
	      = l->exits->find_slot_with_hash (e, htab_hash_pointer (e),
					       NO_INSERT);
	    if (slot)
	      l->exits->clear_slot (slot);
	  }
    }

  /* Adjust the number of blocks in the tree root of the outlined part.  */
  get_loop (dest_cfun, 0)->num_nodes = bbs.length () + 2;

  /* Setup a mapping to be used by move_block_to_fn.  */
  loop->aux = current_loops->tree_root;
  loop0->aux = current_loops->tree_root;

  /* Fix up orig_loop_num.  If the block referenced in it has been moved
     to dest_cfun, update orig_loop_num field, otherwise clear it.  */
  signed char *moved_orig_loop_num = NULL;
  for (auto dloop : loops_list (dest_cfun, 0))
    if (dloop->orig_loop_num)
      {
	if (moved_orig_loop_num == NULL)
	  moved_orig_loop_num
	    = XCNEWVEC (signed char, vec_safe_length (larray));
	if ((*larray)[dloop->orig_loop_num] != NULL
	    && get_loop (saved_cfun, dloop->orig_loop_num) == NULL)
	  {
	    if (moved_orig_loop_num[dloop->orig_loop_num] >= 0
		&& moved_orig_loop_num[dloop->orig_loop_num] < 2)
	      moved_orig_loop_num[dloop->orig_loop_num]++;
	    dloop->orig_loop_num = (*larray)[dloop->orig_loop_num]->num;
	  }
	else
	  {
	    moved_orig_loop_num[dloop->orig_loop_num] = -1;
	    dloop->orig_loop_num = 0;
	  }
      }
  pop_cfun ();

  if (moved_orig_loop_num)
    {
      FOR_EACH_VEC_ELT (bbs, i, bb)
	{
	  gimple *g = find_loop_dist_alias (bb);
	  if (g == NULL)
	    continue;

	  int orig_loop_num = tree_to_shwi (gimple_call_arg (g, 0));
	  gcc_assert (orig_loop_num
		      && (unsigned) orig_loop_num < vec_safe_length (larray));
	  if (moved_orig_loop_num[orig_loop_num] == 2)
	    {
	      /* If we have moved both loops with this orig_loop_num into
		 dest_cfun and the LOOP_DIST_ALIAS call is being moved there
		 too, update the first argument.  */
	      gcc_assert ((*larray)[orig_loop_num] != NULL
			  && (get_loop (saved_cfun, orig_loop_num) == NULL));
	      tree t = build_int_cst (integer_type_node,
				      (*larray)[orig_loop_num]->num);
	      gimple_call_set_arg (g, 0, t);
	      update_stmt (g);
	      /* Make sure the following loop will not update it.  */
	      moved_orig_loop_num[orig_loop_num] = 0;
	    }
	  else
	    /* Otherwise at least one of the loops stayed in saved_cfun.
	       Remove the LOOP_DIST_ALIAS call.  */
	    fold_loop_internal_call (g, gimple_call_arg (g, 1));
	}
      FOR_EACH_BB_FN (bb, saved_cfun)
	{
	  gimple *g = find_loop_dist_alias (bb);
	  if (g == NULL)
	    continue;
	  int orig_loop_num = tree_to_shwi (gimple_call_arg (g, 0));
	  gcc_assert (orig_loop_num
		      && (unsigned) orig_loop_num < vec_safe_length (larray));
	  if (moved_orig_loop_num[orig_loop_num])
	    /* LOOP_DIST_ALIAS call remained in saved_cfun, if at least one
	       of the corresponding loops was moved, remove it.  */
	    fold_loop_internal_call (g, gimple_call_arg (g, 1));
	}
      XDELETEVEC (moved_orig_loop_num);
    }
  ggc_free (larray);

  /* Move blocks from BBS into DEST_CFUN.  */
  gcc_assert (bbs.length () >= 2);
  after = dest_cfun->cfg->x_entry_block_ptr;
  hash_map<tree, tree> vars_map;

  memset (&d, 0, sizeof (d));
  d.orig_block = orig_block;
  d.new_block = DECL_INITIAL (dest_cfun->decl);
  d.from_context = cfun->decl;
  d.to_context = dest_cfun->decl;
  d.vars_map = &vars_map;
  d.new_label_map = new_label_map;
  d.eh_map = eh_map;
  d.remap_decls_p = true;

  if (gimple_in_ssa_p (cfun))
    for (tree arg = DECL_ARGUMENTS (d.to_context); arg; arg = DECL_CHAIN (arg))
      {
	tree narg = make_ssa_name_fn (dest_cfun, arg, gimple_build_nop ());
	set_ssa_default_def (dest_cfun, arg, narg);
	vars_map.put (arg, narg);
      }

  FOR_EACH_VEC_ELT (bbs, i, bb)
    {
      /* No need to update edge counts on the last block.  It has
	 already been updated earlier when we detached the region from
	 the original CFG.  */
      move_block_to_fn (dest_cfun, bb, after, bb != exit_bb, &d);
      after = bb;
    }

  /* Adjust the maximum clique used.  */
  dest_cfun->last_clique = saved_cfun->last_clique;

  loop->aux = NULL;
  loop0->aux = NULL;
  /* Loop sizes are no longer correct, fix them up.  */
  loop->num_nodes -= num_nodes;
  for (class loop *outer = loop_outer (loop);
       outer; outer = loop_outer (outer))
    outer->num_nodes -= num_nodes;
  loop0->num_nodes -= bbs.length () - num_nodes;

  if (saved_cfun->has_simduid_loops || saved_cfun->has_force_vectorize_loops)
    {
      class loop *aloop;
      for (i = 0; vec_safe_iterate (loops->larray, i, &aloop); i++)
	if (aloop != NULL)
	  {
	    if (aloop->simduid)
	      {
		replace_by_duplicate_decl (&aloop->simduid, d.vars_map,
					   d.to_context);
		dest_cfun->has_simduid_loops = true;
	      }
	    if (aloop->force_vectorize)
	      dest_cfun->has_force_vectorize_loops = true;
	  }
    }

  /* Rewire BLOCK_SUBBLOCKS of orig_block.  */
  if (orig_block)
    {
      tree block;
      gcc_assert (BLOCK_SUBBLOCKS (DECL_INITIAL (dest_cfun->decl))
		  == NULL_TREE);
      BLOCK_SUBBLOCKS (DECL_INITIAL (dest_cfun->decl))
	= BLOCK_SUBBLOCKS (orig_block);
      for (block = BLOCK_SUBBLOCKS (orig_block);
	   block; block = BLOCK_CHAIN (block))
	BLOCK_SUPERCONTEXT (block) = DECL_INITIAL (dest_cfun->decl);
      BLOCK_SUBBLOCKS (orig_block) = NULL_TREE;
    }

  replace_block_vars_by_duplicates (DECL_INITIAL (dest_cfun->decl),
				    &vars_map, dest_cfun->decl);

  if (new_label_map)
    htab_delete (new_label_map);
  if (eh_map)
    delete eh_map;

  /* We need to release ssa-names in a defined order, so first find them,
     and then iterate in ascending version order.  */
  bitmap release_names = BITMAP_ALLOC (NULL);
  vars_map.traverse<void *, gather_ssa_name_hash_map_from> (release_names);
  bitmap_iterator bi;
  EXECUTE_IF_SET_IN_BITMAP (release_names, 0, i, bi)
    release_ssa_name (ssa_name (i));
  BITMAP_FREE (release_names);

  /* Rewire the entry and exit blocks.  The successor to the entry
     block turns into the successor of DEST_FN's ENTRY_BLOCK_PTR in
     the child function.  Similarly, the predecessor of DEST_FN's
     EXIT_BLOCK_PTR turns into the predecessor of EXIT_BLOCK_PTR.  We
     need to switch CFUN between DEST_CFUN and SAVED_CFUN so that the
     various CFG manipulation function get to the right CFG.

     FIXME, this is silly.  The CFG ought to become a parameter to
     these helpers.  */
  push_cfun (dest_cfun);
  ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = entry_bb->count;
  make_single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun), entry_bb, EDGE_FALLTHRU);
  if (exit_bb)
    {
      make_single_succ_edge (exit_bb,  EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
      EXIT_BLOCK_PTR_FOR_FN (cfun)->count = exit_bb->count;
    }
  else
    EXIT_BLOCK_PTR_FOR_FN (cfun)->count = profile_count::zero ();
  pop_cfun ();

  /* Back in the original function, the SESE region has disappeared,
     create a new basic block in its place.  */
  bb = create_empty_bb (entry_pred[0]);
  if (current_loops)
    add_bb_to_loop (bb, loop);
  for (i = 0; i < num_entry_edges; i++)
    {
      e = make_edge (entry_pred[i], bb, entry_flag[i]);
      e->probability = entry_prob[i];
    }

  for (i = 0; i < num_exit_edges; i++)
    {
      e = make_edge (bb, exit_succ[i], exit_flag[i]);
      e->probability = exit_prob[i];
    }

  set_immediate_dominator (CDI_DOMINATORS, bb, dom_entry);
  FOR_EACH_VEC_ELT (dom_bbs, i, abb)
    set_immediate_dominator (CDI_DOMINATORS, abb, bb);

  if (exit_bb)
    {
      free (exit_prob);
      free (exit_flag);
      free (exit_succ);
    }
  free (entry_prob);
  free (entry_flag);
  free (entry_pred);
  bbs.release ();

  return bb;
}

/* Dump default def DEF to file FILE using FLAGS and indentation
   SPC.  */

static void
dump_default_def (FILE *file, tree def, int spc, dump_flags_t flags)
{
  for (int i = 0; i < spc; ++i)
    fprintf (file, " ");
  dump_ssaname_info_to_file (file, def, spc);

  print_generic_expr (file, TREE_TYPE (def), flags);
  fprintf (file, " ");
  print_generic_expr (file, def, flags);
  fprintf (file, " = ");
  print_generic_expr (file, SSA_NAME_VAR (def), flags);
  fprintf (file, ";\n");
}

/* Print no_sanitize attribute to FILE for a given attribute VALUE.  */

static void
print_no_sanitize_attr_value (FILE *file, tree value)
{
  unsigned int flags = tree_to_uhwi (value);
  bool first = true;
  for (int i = 0; sanitizer_opts[i].name != NULL; ++i)
    {
      if ((sanitizer_opts[i].flag & flags) == sanitizer_opts[i].flag)
	{
	  if (!first)
	    fprintf (file, " | ");
	  fprintf (file, "%s", sanitizer_opts[i].name);
	  first = false;
	}
    }
}

/* Dump FUNCTION_DECL FN to file FILE using FLAGS (see TDF_* in dumpfile.h)
   */

void
dump_function_to_file (tree fndecl, FILE *file, dump_flags_t flags)
{
  tree arg, var, old_current_fndecl = current_function_decl;
  struct function *dsf;
  bool ignore_topmost_bind = false, any_var = false;
  basic_block bb;
  tree chain;
  bool tmclone = (TREE_CODE (fndecl) == FUNCTION_DECL
		  && decl_is_tm_clone (fndecl));
  struct function *fun = DECL_STRUCT_FUNCTION (fndecl);

  tree fntype = TREE_TYPE (fndecl);
  tree attrs[] = { DECL_ATTRIBUTES (fndecl), TYPE_ATTRIBUTES (fntype) };

  for (int i = 0; i != 2; ++i)
    {
      if (!attrs[i])
	continue;

      fprintf (file, "__attribute__((");

      bool first = true;
      tree chain;
      for (chain = attrs[i]; chain; first = false, chain = TREE_CHAIN (chain))
	{
	  if (!first)
	    fprintf (file, ", ");

	  tree name = get_attribute_name (chain);
	  print_generic_expr (file, name, dump_flags);
	  if (TREE_VALUE (chain) != NULL_TREE)
	    {
	      fprintf (file, " (");

	      if (strstr (IDENTIFIER_POINTER (name), "no_sanitize"))
		print_no_sanitize_attr_value (file, TREE_VALUE (chain));
	      else
		print_generic_expr (file, TREE_VALUE (chain), dump_flags);
	      fprintf (file, ")");
	    }
	}

      fprintf (file, "))\n");
    }

  current_function_decl = fndecl;
  if (flags & TDF_GIMPLE)
    {
      static bool hotness_bb_param_printed = false;
      if (profile_info != NULL
	  && !hotness_bb_param_printed)
	{
	  hotness_bb_param_printed = true;
	  fprintf (file,
		   "/* --param=gimple-fe-computed-hot-bb-threshold=%" PRId64
		   " */\n", get_hot_bb_threshold ());
	}

      print_generic_expr (file, TREE_TYPE (TREE_TYPE (fndecl)),
			  dump_flags | TDF_SLIM);
      fprintf (file, " __GIMPLE (%s",
	       (fun->curr_properties & PROP_ssa) ? "ssa"
	       : (fun->curr_properties & PROP_cfg) ? "cfg"
	       : "");

      if (fun && fun->cfg)
	{
	  basic_block bb = ENTRY_BLOCK_PTR_FOR_FN (fun);
	  if (bb->count.initialized_p ())
	    fprintf (file, ",%s(%" PRIu64 ")",
		     profile_quality_as_string (bb->count.quality ()),
		     bb->count.value ());
	  if (dump_flags & TDF_UID)
	    fprintf (file, ")\n%sD_%u (", function_name (fun),
		     DECL_UID (fndecl));
	  else
	    fprintf (file, ")\n%s (", function_name (fun));
	}
    }
  else
    {
      print_generic_expr (file, TREE_TYPE (fntype), dump_flags);
      if (dump_flags & TDF_UID)
	fprintf (file, " %sD.%u %s(", function_name (fun), DECL_UID (fndecl),
		 tmclone ? "[tm-clone] " : "");
      else
	fprintf (file, " %s %s(", function_name (fun),
		 tmclone ? "[tm-clone] " : "");
    }

  arg = DECL_ARGUMENTS (fndecl);
  while (arg)
    {
      print_generic_expr (file, TREE_TYPE (arg), dump_flags);
      fprintf (file, " ");
      print_generic_expr (file, arg, dump_flags);
      if (DECL_CHAIN (arg))
	fprintf (file, ", ");
      arg = DECL_CHAIN (arg);
    }
  fprintf (file, ")\n");

  dsf = DECL_STRUCT_FUNCTION (fndecl);
  if (dsf && (flags & TDF_EH))
    dump_eh_tree (file, dsf);

  if (flags & TDF_RAW && !gimple_has_body_p (fndecl))
    {
      dump_node (fndecl, TDF_SLIM | flags, file);
      current_function_decl = old_current_fndecl;
      return;
    }

  /* When GIMPLE is lowered, the variables are no longer available in
     BIND_EXPRs, so display them separately.  */
  if (fun && fun->decl == fndecl && (fun->curr_properties & PROP_gimple_lcf))
    {
      unsigned ix;
      ignore_topmost_bind = true;

      fprintf (file, "{\n");
      if (gimple_in_ssa_p (fun)
	  && (flags & TDF_ALIAS))
	{
	  for (arg = DECL_ARGUMENTS (fndecl); arg != NULL;
	       arg = DECL_CHAIN (arg))
	    {
	      tree def = ssa_default_def (fun, arg);
	      if (def)
		dump_default_def (file, def, 2, flags);
	    }

	  tree res = DECL_RESULT (fun->decl);
	  if (res != NULL_TREE
	      && DECL_BY_REFERENCE (res))
	    {
	      tree def = ssa_default_def (fun, res);
	      if (def)
		dump_default_def (file, def, 2, flags);
	    }

	  tree static_chain = fun->static_chain_decl;
	  if (static_chain != NULL_TREE)
	    {
	      tree def = ssa_default_def (fun, static_chain);
	      if (def)
		dump_default_def (file, def, 2, flags);
	    }
	}

      if (!vec_safe_is_empty (fun->local_decls))
	FOR_EACH_LOCAL_DECL (fun, ix, var)
	  {
	    print_generic_decl (file, var, flags);
	    fprintf (file, "\n");

	    any_var = true;
	  }

      tree name;

      if (gimple_in_ssa_p (fun))
	FOR_EACH_SSA_NAME (ix, name, fun)
	  {
	    if (!SSA_NAME_VAR (name)
		/* SSA name with decls without a name still get
		   dumped as _N, list those explicitely as well even
		   though we've dumped the decl declaration as D.xxx
		   above.  */
		|| !SSA_NAME_IDENTIFIER (name))
	      {
		fprintf (file, "  ");
		print_generic_expr (file, TREE_TYPE (name), flags);
		fprintf (file, " ");
		print_generic_expr (file, name, flags);
		fprintf (file, ";\n");

		any_var = true;
	      }
	  }
    }

  if (fun && fun->decl == fndecl
      && fun->cfg
      && basic_block_info_for_fn (fun))
    {
      /* If the CFG has been built, emit a CFG-based dump.  */
      if (!ignore_topmost_bind)
	fprintf (file, "{\n");

      if (any_var && n_basic_blocks_for_fn (fun))
	fprintf (file, "\n");

      FOR_EACH_BB_FN (bb, fun)
	dump_bb (file, bb, 2, flags);

      fprintf (file, "}\n");
    }
  else if (fun && (fun->curr_properties & PROP_gimple_any))
    {
      /* The function is now in GIMPLE form but the CFG has not been
	 built yet.  Emit the single sequence of GIMPLE statements
	 that make up its body.  */
      gimple_seq body = gimple_body (fndecl);

      if (gimple_seq_first_stmt (body)
	  && gimple_seq_first_stmt (body) == gimple_seq_last_stmt (body)
	  && gimple_code (gimple_seq_first_stmt (body)) == GIMPLE_BIND)
	print_gimple_seq (file, body, 0, flags);
      else
	{
	  if (!ignore_topmost_bind)
	    fprintf (file, "{\n");

	  if (any_var)
	    fprintf (file, "\n");

	  print_gimple_seq (file, body, 2, flags);
	  fprintf (file, "}\n");
	}
    }
  else
    {
      int indent;

      /* Make a tree based dump.  */
      chain = DECL_SAVED_TREE (fndecl);
      if (chain && TREE_CODE (chain) == BIND_EXPR)
	{
	  if (ignore_topmost_bind)
	    {
	      chain = BIND_EXPR_BODY (chain);
	      indent = 2;
	    }
	  else
	    indent = 0;
	}
      else
	{
	  if (!ignore_topmost_bind)
	    {
	      fprintf (file, "{\n");
	      /* No topmost bind, pretend it's ignored for later.  */
	      ignore_topmost_bind = true;
	    }
	  indent = 2;
	}

      if (any_var)
	fprintf (file, "\n");

      print_generic_stmt_indented (file, chain, flags, indent);
      if (ignore_topmost_bind)
	fprintf (file, "}\n");
    }

  if (flags & TDF_ENUMERATE_LOCALS)
    dump_enumerated_decls (file, flags);
  fprintf (file, "\n\n");

  current_function_decl = old_current_fndecl;
}

/* Dump FUNCTION_DECL FN to stderr using FLAGS (see TDF_* in tree.h)  */

DEBUG_FUNCTION void
debug_function (tree fn, dump_flags_t flags)
{
  dump_function_to_file (fn, stderr, flags);
}


/* Print on FILE the indexes for the predecessors of basic_block BB.  */

static void
print_pred_bbs (FILE *file, basic_block bb)
{
  edge e;
  edge_iterator ei;

  FOR_EACH_EDGE (e, ei, bb->preds)
    fprintf (file, "bb_%d ", e->src->index);
}


/* Print on FILE the indexes for the successors of basic_block BB.  */

static void
print_succ_bbs (FILE *file, basic_block bb)
{
  edge e;
  edge_iterator ei;

  FOR_EACH_EDGE (e, ei, bb->succs)
    fprintf (file, "bb_%d ", e->dest->index);
}

/* Print to FILE the basic block BB following the VERBOSITY level.  */

void
print_loops_bb (FILE *file, basic_block bb, int indent, int verbosity)
{
  char *s_indent = (char *) alloca ((size_t) indent + 1);
  memset ((void *) s_indent, ' ', (size_t) indent);
  s_indent[indent] = '\0';

  /* Print basic_block's header.  */
  if (verbosity >= 2)
    {
      fprintf (file, "%s  bb_%d (preds = {", s_indent, bb->index);
      print_pred_bbs (file, bb);
      fprintf (file, "}, succs = {");
      print_succ_bbs (file, bb);
      fprintf (file, "})\n");
    }

  /* Print basic_block's body.  */
  if (verbosity >= 3)
    {
      fprintf (file, "%s  {\n", s_indent);
      dump_bb (file, bb, indent + 4, TDF_VOPS|TDF_MEMSYMS);
      fprintf (file, "%s  }\n", s_indent);
    }
}

static void print_loop_and_siblings (FILE *, class loop *, int, int);

/* Pretty print LOOP on FILE, indented INDENT spaces.  Following
   VERBOSITY level this outputs the contents of the loop, or just its
   structure.  */

static void
print_loop (FILE *file, class loop *loop, int indent, int verbosity)
{
  char *s_indent;
  basic_block bb;

  if (loop == NULL)
    return;

  s_indent = (char *) alloca ((size_t) indent + 1);
  memset ((void *) s_indent, ' ', (size_t) indent);
  s_indent[indent] = '\0';

  /* Print loop's header.  */
  fprintf (file, "%sloop_%d (", s_indent, loop->num);
  if (loop->header)
    fprintf (file, "header = %d", loop->header->index);
  else
    {
      fprintf (file, "deleted)\n");
      return;
    }
  if (loop->latch)
    fprintf (file, ", latch = %d", loop->latch->index);
  else
    fprintf (file, ", multiple latches");
  fprintf (file, ", niter = ");
  print_generic_expr (file, loop->nb_iterations);

  if (loop->any_upper_bound)
    {
      fprintf (file, ", upper_bound = ");
      print_decu (loop->nb_iterations_upper_bound, file);
    }
  if (loop->any_likely_upper_bound)
    {
      fprintf (file, ", likely_upper_bound = ");
      print_decu (loop->nb_iterations_likely_upper_bound, file);
    }

  if (loop->any_estimate)
    {
      fprintf (file, ", estimate = ");
      print_decu (loop->nb_iterations_estimate, file);
    }
  if (loop->unroll)
    fprintf (file, ", unroll = %d", loop->unroll);
  fprintf (file, ")\n");

  /* Print loop's body.  */
  if (verbosity >= 1)
    {
      fprintf (file, "%s{\n", s_indent);
      FOR_EACH_BB_FN (bb, cfun)
	if (bb->loop_father == loop)
	  print_loops_bb (file, bb, indent, verbosity);

      print_loop_and_siblings (file, loop->inner, indent + 2, verbosity);
      fprintf (file, "%s}\n", s_indent);
    }
}

/* Print the LOOP and its sibling loops on FILE, indented INDENT
   spaces.  Following VERBOSITY level this outputs the contents of the
   loop, or just its structure.  */

static void
print_loop_and_siblings (FILE *file, class loop *loop, int indent,
			 int verbosity)
{
  if (loop == NULL)
    return;

  print_loop (file, loop, indent, verbosity);
  print_loop_and_siblings (file, loop->next, indent, verbosity);
}

/* Follow a CFG edge from the entry point of the program, and on entry
   of a loop, pretty print the loop structure on FILE.  */

void
print_loops (FILE *file, int verbosity)
{
  basic_block bb;

  bb = ENTRY_BLOCK_PTR_FOR_FN (cfun);
  fprintf (file, "\nLoops in function: %s\n", current_function_name ());
  if (bb && bb->loop_father)
    print_loop_and_siblings (file, bb->loop_father, 0, verbosity);
}

/* Dump a loop.  */

DEBUG_FUNCTION void
debug (class loop &ref)
{
  print_loop (stderr, &ref, 0, /*verbosity*/0);
}

DEBUG_FUNCTION void
debug (class loop *ptr)
{
  if (ptr)
    debug (*ptr);
  else
    fprintf (stderr, "<nil>\n");
}

/* Dump a loop verbosely.  */

DEBUG_FUNCTION void
debug_verbose (class loop &ref)
{
  print_loop (stderr, &ref, 0, /*verbosity*/3);
}

DEBUG_FUNCTION void
debug_verbose (class loop *ptr)
{
  if (ptr)
    debug (*ptr);
  else
    fprintf (stderr, "<nil>\n");
}


/* Debugging loops structure at tree level, at some VERBOSITY level.  */

DEBUG_FUNCTION void
debug_loops (int verbosity)
{
  print_loops (stderr, verbosity);
}

/* Print on stderr the code of LOOP, at some VERBOSITY level.  */

DEBUG_FUNCTION void
debug_loop (class loop *loop, int verbosity)
{
  print_loop (stderr, loop, 0, verbosity);
}

/* Print on stderr the code of loop number NUM, at some VERBOSITY
   level.  */

DEBUG_FUNCTION void
debug_loop_num (unsigned num, int verbosity)
{
  debug_loop (get_loop (cfun, num), verbosity);
}

/* Return true if BB ends with a call, possibly followed by some
   instructions that must stay with the call.  Return false,
   otherwise.  */

static bool
gimple_block_ends_with_call_p (basic_block bb)
{
  gimple_stmt_iterator gsi = gsi_last_nondebug_bb (bb);
  return !gsi_end_p (gsi) && is_gimple_call (gsi_stmt (gsi));
}


/* Return true if BB ends with a conditional branch.  Return false,
   otherwise.  */

static bool
gimple_block_ends_with_condjump_p (const_basic_block bb)
{
  gimple *stmt = last_stmt (CONST_CAST_BB (bb));
  return (stmt && gimple_code (stmt) == GIMPLE_COND);
}


/* Return true if statement T may terminate execution of BB in ways not
   explicitly represtented in the CFG.  */

bool
stmt_can_terminate_bb_p (gimple *t)
{
  tree fndecl = NULL_TREE;
  int call_flags = 0;

  /* Eh exception not handled internally terminates execution of the whole
     function.  */
  if (stmt_can_throw_external (cfun, t))
    return true;

  /* NORETURN and LONGJMP calls already have an edge to exit.
     CONST and PURE calls do not need one.
     We don't currently check for CONST and PURE here, although
     it would be a good idea, because those attributes are
     figured out from the RTL in mark_constant_function, and
     the counter incrementation code from -fprofile-arcs
     leads to different results from -fbranch-probabilities.  */
  if (is_gimple_call (t))
    {
      fndecl = gimple_call_fndecl (t);
      call_flags = gimple_call_flags (t);
    }

  if (is_gimple_call (t)
      && fndecl
      && fndecl_built_in_p (fndecl)
      && (call_flags & ECF_NOTHROW)
      && !(call_flags & ECF_RETURNS_TWICE)
      /* fork() doesn't really return twice, but the effect of
	 wrapping it in __gcov_fork() which calls __gcov_dump() and
	 __gcov_reset() and clears the counters before forking has the same
	 effect as returning twice.  Force a fake edge.  */
      && !fndecl_built_in_p (fndecl, BUILT_IN_FORK))
    return false;

  if (is_gimple_call (t))
    {
      edge_iterator ei;
      edge e;
      basic_block bb;

      if (call_flags & (ECF_PURE | ECF_CONST)
	  && !(call_flags & ECF_LOOPING_CONST_OR_PURE))
	return false;

      /* Function call may do longjmp, terminate program or do other things.
	 Special case noreturn that have non-abnormal edges out as in this case
	 the fact is sufficiently represented by lack of edges out of T.  */
      if (!(call_flags & ECF_NORETURN))
	return true;

      bb = gimple_bb (t);
      FOR_EACH_EDGE (e, ei, bb->succs)
	if ((e->flags & EDGE_FAKE) == 0)
	  return true;
    }

  if (gasm *asm_stmt = dyn_cast <gasm *> (t))
    if (gimple_asm_volatile_p (asm_stmt) || gimple_asm_input_p (asm_stmt))
      return true;

  return false;
}


/* Add fake edges to the function exit for any non constant and non
   noreturn calls (or noreturn calls with EH/abnormal edges),
   volatile inline assembly in the bitmap of blocks specified by BLOCKS
   or to the whole CFG if BLOCKS is zero.  Return the number of blocks
   that were split.

   The goal is to expose cases in which entering a basic block does
   not imply that all subsequent instructions must be executed.  */

static int
gimple_flow_call_edges_add (sbitmap blocks)
{
  int i;
  int blocks_split = 0;
  int last_bb = last_basic_block_for_fn (cfun);
  bool check_last_block = false;

  if (n_basic_blocks_for_fn (cfun) == NUM_FIXED_BLOCKS)
    return 0;

  if (! blocks)
    check_last_block = true;
  else
    check_last_block = bitmap_bit_p (blocks,
				     EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb->index);

  /* In the last basic block, before epilogue generation, there will be
     a fallthru edge to EXIT.  Special care is required if the last insn
     of the last basic block is a call because make_edge folds duplicate
     edges, which would result in the fallthru edge also being marked
     fake, which would result in the fallthru edge being removed by
     remove_fake_edges, which would result in an invalid CFG.

     Moreover, we can't elide the outgoing fake edge, since the block
     profiler needs to take this into account in order to solve the minimal
     spanning tree in the case that the call doesn't return.

     Handle this by adding a dummy instruction in a new last basic block.  */
  if (check_last_block)
    {
      basic_block bb = EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb;
      gimple_stmt_iterator gsi = gsi_last_nondebug_bb (bb);
      gimple *t = NULL;

      if (!gsi_end_p (gsi))
	t = gsi_stmt (gsi);

      if (t && stmt_can_terminate_bb_p (t))
	{
	  edge e;

	  e = find_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun));
	  if (e)
	    {
	      gsi_insert_on_edge (e, gimple_build_nop ());
	      gsi_commit_edge_inserts ();
	    }
	}
    }

  /* Now add fake edges to the function exit for any non constant
     calls since there is no way that we can determine if they will
     return or not...  */
  for (i = 0; i < last_bb; i++)
    {
      basic_block bb = BASIC_BLOCK_FOR_FN (cfun, i);
      gimple_stmt_iterator gsi;
      gimple *stmt, *last_stmt;

      if (!bb)
	continue;

      if (blocks && !bitmap_bit_p (blocks, i))
	continue;

      gsi = gsi_last_nondebug_bb (bb);
      if (!gsi_end_p (gsi))
	{
	  last_stmt = gsi_stmt (gsi);
	  do
	    {
	      stmt = gsi_stmt (gsi);
	      if (stmt_can_terminate_bb_p (stmt))
		{
		  edge e;

		  /* The handling above of the final block before the
		     epilogue should be enough to verify that there is
		     no edge to the exit block in CFG already.
		     Calling make_edge in such case would cause us to
		     mark that edge as fake and remove it later.  */
		  if (flag_checking && stmt == last_stmt)
		    {
		      e = find_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun));
		      gcc_assert (e == NULL);
		    }

		  /* Note that the following may create a new basic block
		     and renumber the existing basic blocks.  */
		  if (stmt != last_stmt)
		    {
		      e = split_block (bb, stmt);
		      if (e)
			blocks_split++;
		    }
		  e = make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), EDGE_FAKE);
		  e->probability = profile_probability::guessed_never ();
		}
	      gsi_prev (&gsi);
	    }
	  while (!gsi_end_p (gsi));
	}
    }

  if (blocks_split)
    checking_verify_flow_info ();

  return blocks_split;
}

/* Removes edge E and all the blocks dominated by it, and updates dominance
   information.  The IL in E->src needs to be updated separately.
   If dominance info is not available, only the edge E is removed.*/

void
remove_edge_and_dominated_blocks (edge e)
{
  vec<basic_block> bbs_to_fix_dom = vNULL;
  edge f;
  edge_iterator ei;
  bool none_removed = false;
  unsigned i;
  basic_block bb, dbb;
  bitmap_iterator bi;

  /* If we are removing a path inside a non-root loop that may change
     loop ownership of blocks or remove loops.  Mark loops for fixup.  */
  if (current_loops
      && loop_outer (e->src->loop_father) != NULL
      && e->src->loop_father == e->dest->loop_father)
    loops_state_set (LOOPS_NEED_FIXUP);

  if (!dom_info_available_p (CDI_DOMINATORS))
    {
      remove_edge (e);
      return;
    }

  /* No updating is needed for edges to exit.  */
  if (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
    {
      if (cfgcleanup_altered_bbs)
	bitmap_set_bit (cfgcleanup_altered_bbs, e->src->index);
      remove_edge (e);
      return;
    }

  /* First, we find the basic blocks to remove.  If E->dest has a predecessor
     that is not dominated by E->dest, then this set is empty.  Otherwise,
     all the basic blocks dominated by E->dest are removed.

     Also, to DF_IDOM we store the immediate dominators of the blocks in
     the dominance frontier of E (i.e., of the successors of the
     removed blocks, if there are any, and of E->dest otherwise).  */
  FOR_EACH_EDGE (f, ei, e->dest->preds)
    {
      if (f == e)
	continue;

      if (!dominated_by_p (CDI_DOMINATORS, f->src, e->dest))
	{
	  none_removed = true;
	  break;
	}
    }

  auto_bitmap df, df_idom;
  auto_vec<basic_block> bbs_to_remove;
  if (none_removed)
    bitmap_set_bit (df_idom,
		    get_immediate_dominator (CDI_DOMINATORS, e->dest)->index);
  else
    {
      bbs_to_remove = get_all_dominated_blocks (CDI_DOMINATORS, e->dest);
      FOR_EACH_VEC_ELT (bbs_to_remove, i, bb)
	{
	  FOR_EACH_EDGE (f, ei, bb->succs)
	    {
	      if (f->dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
		bitmap_set_bit (df, f->dest->index);
	    }
	}
      FOR_EACH_VEC_ELT (bbs_to_remove, i, bb)
	bitmap_clear_bit (df, bb->index);

      EXECUTE_IF_SET_IN_BITMAP (df, 0, i, bi)
	{
	  bb = BASIC_BLOCK_FOR_FN (cfun, i);
	  bitmap_set_bit (df_idom,
			  get_immediate_dominator (CDI_DOMINATORS, bb)->index);
	}
    }

  if (cfgcleanup_altered_bbs)
    {
      /* Record the set of the altered basic blocks.  */
      bitmap_set_bit (cfgcleanup_altered_bbs, e->src->index);
      bitmap_ior_into (cfgcleanup_altered_bbs, df);
    }

  /* Remove E and the cancelled blocks.  */
  if (none_removed)
    remove_edge (e);
  else
    {
      /* Walk backwards so as to get a chance to substitute all
	 released DEFs into debug stmts.  See
	 eliminate_unnecessary_stmts() in tree-ssa-dce.cc for more
	 details.  */
      for (i = bbs_to_remove.length (); i-- > 0; )
	delete_basic_block (bbs_to_remove[i]);
    }

  /* Update the dominance information.  The immediate dominator may change only
     for blocks whose immediate dominator belongs to DF_IDOM:

     Suppose that idom(X) = Y before removal of E and idom(X) != Y after the
     removal.  Let Z the arbitrary block such that idom(Z) = Y and
     Z dominates X after the removal.  Before removal, there exists a path P
     from Y to X that avoids Z.  Let F be the last edge on P that is
     removed, and let W = F->dest.  Before removal, idom(W) = Y (since Y
     dominates W, and because of P, Z does not dominate W), and W belongs to
     the dominance frontier of E.  Therefore, Y belongs to DF_IDOM.  */
  EXECUTE_IF_SET_IN_BITMAP (df_idom, 0, i, bi)
    {
      bb = BASIC_BLOCK_FOR_FN (cfun, i);
      for (dbb = first_dom_son (CDI_DOMINATORS, bb);
	   dbb;
	   dbb = next_dom_son (CDI_DOMINATORS, dbb))
	bbs_to_fix_dom.safe_push (dbb);
    }

  iterate_fix_dominators (CDI_DOMINATORS, bbs_to_fix_dom, true);

  bbs_to_fix_dom.release ();
}

/* Purge dead EH edges from basic block BB.  */

bool
gimple_purge_dead_eh_edges (basic_block bb)
{
  bool changed = false;
  edge e;
  edge_iterator ei;
  gimple *stmt = last_stmt (bb);

  if (stmt && stmt_can_throw_internal (cfun, stmt))
    return false;

  for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
    {
      if (e->flags & EDGE_EH)
	{
	  remove_edge_and_dominated_blocks (e);
	  changed = true;
	}
      else
	ei_next (&ei);
    }

  return changed;
}

/* Purge dead EH edges from basic block listed in BLOCKS.  */

bool
gimple_purge_all_dead_eh_edges (const_bitmap blocks)
{
  bool changed = false;
  unsigned i;
  bitmap_iterator bi;

  EXECUTE_IF_SET_IN_BITMAP (blocks, 0, i, bi)
    {
      basic_block bb = BASIC_BLOCK_FOR_FN (cfun, i);

      /* Earlier gimple_purge_dead_eh_edges could have removed
	 this basic block already.  */
      gcc_assert (bb || changed);
      if (bb != NULL)
	changed |= gimple_purge_dead_eh_edges (bb);
    }

  return changed;
}

/* Purge dead abnormal call edges from basic block BB.  */

bool
gimple_purge_dead_abnormal_call_edges (basic_block bb)
{
  bool changed = false;
  edge e;
  edge_iterator ei;
  gimple *stmt = last_stmt (bb);

  if (stmt && stmt_can_make_abnormal_goto (stmt))
    return false;

  for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
    {
      if (e->flags & EDGE_ABNORMAL)
	{
	  if (e->flags & EDGE_FALLTHRU)
	    e->flags &= ~EDGE_ABNORMAL;
	  else
	    remove_edge_and_dominated_blocks (e);
	  changed = true;
	}
      else
	ei_next (&ei);
    }

  return changed;
}

/* Purge dead abnormal call edges from basic block listed in BLOCKS.  */

bool
gimple_purge_all_dead_abnormal_call_edges (const_bitmap blocks)
{
  bool changed = false;
  unsigned i;
  bitmap_iterator bi;

  EXECUTE_IF_SET_IN_BITMAP (blocks, 0, i, bi)
    {
      basic_block bb = BASIC_BLOCK_FOR_FN (cfun, i);

      /* Earlier gimple_purge_dead_abnormal_call_edges could have removed
	 this basic block already.  */
      gcc_assert (bb || changed);
      if (bb != NULL)
	changed |= gimple_purge_dead_abnormal_call_edges (bb);
    }

  return changed;
}

/* This function is called whenever a new edge is created or
   redirected.  */

static void
gimple_execute_on_growing_pred (edge e)
{
  basic_block bb = e->dest;

  if (!gimple_seq_empty_p (phi_nodes (bb)))
    reserve_phi_args_for_new_edge (bb);
}

/* This function is called immediately before edge E is removed from
   the edge vector E->dest->preds.  */

static void
gimple_execute_on_shrinking_pred (edge e)
{
  if (!gimple_seq_empty_p (phi_nodes (e->dest)))
    remove_phi_args (e);
}

/*---------------------------------------------------------------------------
  Helper functions for Loop versioning
  ---------------------------------------------------------------------------*/

/* Adjust phi nodes for 'first' basic block.  'second' basic block is a copy
   of 'first'. Both of them are dominated by 'new_head' basic block. When
   'new_head' was created by 'second's incoming edge it received phi arguments
   on the edge by split_edge(). Later, additional edge 'e' was created to
   connect 'new_head' and 'first'. Now this routine adds phi args on this
   additional edge 'e' that new_head to second edge received as part of edge
   splitting.  */

static void
gimple_lv_adjust_loop_header_phi (basic_block first, basic_block second,
				  basic_block new_head, edge e)
{
  gphi *phi1, *phi2;
  gphi_iterator psi1, psi2;
  tree def;
  edge e2 = find_edge (new_head, second);

  /* Because NEW_HEAD has been created by splitting SECOND's incoming
     edge, we should always have an edge from NEW_HEAD to SECOND.  */
  gcc_assert (e2 != NULL);

  /* Browse all 'second' basic block phi nodes and add phi args to
     edge 'e' for 'first' head. PHI args are always in correct order.  */

  for (psi2 = gsi_start_phis (second),
       psi1 = gsi_start_phis (first);
       !gsi_end_p (psi2) && !gsi_end_p (psi1);
       gsi_next (&psi2),  gsi_next (&psi1))
    {
      phi1 = psi1.phi ();
      phi2 = psi2.phi ();
      def = PHI_ARG_DEF (phi2, e2->dest_idx);
      add_phi_arg (phi1, def, e, gimple_phi_arg_location_from_edge (phi2, e2));
    }
}


/* Adds a if else statement to COND_BB with condition COND_EXPR.
   SECOND_HEAD is the destination of the THEN and FIRST_HEAD is
   the destination of the ELSE part.  */

static void
gimple_lv_add_condition_to_bb (basic_block first_head ATTRIBUTE_UNUSED,
			       basic_block second_head ATTRIBUTE_UNUSED,
			       basic_block cond_bb, void *cond_e)
{
  gimple_stmt_iterator gsi;
  gimple *new_cond_expr;
  tree cond_expr = (tree) cond_e;
  edge e0;

  /* Build new conditional expr */
  gsi = gsi_last_bb (cond_bb);

  cond_expr = force_gimple_operand_gsi_1 (&gsi, cond_expr,
					  is_gimple_condexpr_for_cond,
					  NULL_TREE, false,
					  GSI_CONTINUE_LINKING);
  new_cond_expr = gimple_build_cond_from_tree (cond_expr,
					       NULL_TREE, NULL_TREE);

  /* Add new cond in cond_bb.  */
  gsi_insert_after (&gsi, new_cond_expr, GSI_NEW_STMT);

  /* Adjust edges appropriately to connect new head with first head
     as well as second head.  */
  e0 = single_succ_edge (cond_bb);
  e0->flags &= ~EDGE_FALLTHRU;
  e0->flags |= EDGE_FALSE_VALUE;
}


/* Do book-keeping of basic block BB for the profile consistency checker.
   Store the counting in RECORD.  */
static void
gimple_account_profile_record (basic_block bb,
			       struct profile_record *record)
{
  gimple_stmt_iterator i;
  for (i = gsi_start_nondebug_after_labels_bb (bb); !gsi_end_p (i);
       gsi_next_nondebug (&i))
    {
      record->size
	+= estimate_num_insns (gsi_stmt (i), &eni_size_weights);
      if (profile_info)
	{
	  if (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.ipa ().initialized_p ()
	      && ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.ipa ().nonzero_p ()
	      && bb->count.ipa ().initialized_p ())
	    record->time
	      += estimate_num_insns (gsi_stmt (i),
				     &eni_time_weights)
				     * bb->count.ipa ().to_gcov_type ();
	}
      else if (bb->count.initialized_p ()
	       && ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.initialized_p ())
	record->time
	  += estimate_num_insns
		(gsi_stmt (i),
		 &eni_time_weights)
		 * bb->count.to_sreal_scale
			(ENTRY_BLOCK_PTR_FOR_FN (cfun)->count).to_double ();
     else
      record->time
	+= estimate_num_insns (gsi_stmt (i), &eni_time_weights);
    }
}

struct cfg_hooks gimple_cfg_hooks = {
  "gimple",
  gimple_verify_flow_info,
  gimple_dump_bb,		/* dump_bb  */
  gimple_dump_bb_for_graph,	/* dump_bb_for_graph  */
  create_bb,			/* create_basic_block  */
  gimple_redirect_edge_and_branch, /* redirect_edge_and_branch  */
  gimple_redirect_edge_and_branch_force, /* redirect_edge_and_branch_force  */
  gimple_can_remove_branch_p,	/* can_remove_branch_p  */
  remove_bb,			/* delete_basic_block  */
  gimple_split_block,		/* split_block  */
  gimple_move_block_after,	/* move_block_after  */
  gimple_can_merge_blocks_p,	/* can_merge_blocks_p  */
  gimple_merge_blocks,		/* merge_blocks  */
  gimple_predict_edge,		/* predict_edge  */
  gimple_predicted_by_p,	/* predicted_by_p  */
  gimple_can_duplicate_bb_p,	/* can_duplicate_block_p  */
  gimple_duplicate_bb,		/* duplicate_block  */
  gimple_split_edge,		/* split_edge  */
  gimple_make_forwarder_block,	/* make_forward_block  */
  NULL,				/* tidy_fallthru_edge  */
  NULL,				/* force_nonfallthru */
  gimple_block_ends_with_call_p,/* block_ends_with_call_p */
  gimple_block_ends_with_condjump_p, /* block_ends_with_condjump_p */
  gimple_flow_call_edges_add,   /* flow_call_edges_add */
  gimple_execute_on_growing_pred,	/* execute_on_growing_pred */
  gimple_execute_on_shrinking_pred, /* execute_on_shrinking_pred */
  gimple_duplicate_loop_body_to_header_edge, /* duplicate loop for trees */
  gimple_lv_add_condition_to_bb, /* lv_add_condition_to_bb */
  gimple_lv_adjust_loop_header_phi, /* lv_adjust_loop_header_phi*/
  extract_true_false_edges_from_block, /* extract_cond_bb_edges */
  flush_pending_stmts, 		/* flush_pending_stmts */  
  gimple_empty_block_p,           /* block_empty_p */
  gimple_split_block_before_cond_jump, /* split_block_before_cond_jump */
  gimple_account_profile_record,
};


/* Split all critical edges.  Split some extra (not necessarily critical) edges
   if FOR_EDGE_INSERTION_P is true.  */

unsigned int
split_critical_edges (bool for_edge_insertion_p /* = false */)
{
  basic_block bb;
  edge e;
  edge_iterator ei;

  /* split_edge can redirect edges out of SWITCH_EXPRs, which can get
     expensive.  So we want to enable recording of edge to CASE_LABEL_EXPR
     mappings around the calls to split_edge.  */
  start_recording_case_labels ();
  FOR_ALL_BB_FN (bb, cfun)
    {
      FOR_EACH_EDGE (e, ei, bb->succs)
        {
	  if (EDGE_CRITICAL_P (e) && !(e->flags & EDGE_ABNORMAL))
	    split_edge (e);
	  /* PRE inserts statements to edges and expects that
	     since split_critical_edges was done beforehand, committing edge
	     insertions will not split more edges.  In addition to critical
	     edges we must split edges that have multiple successors and
	     end by control flow statements, such as RESX.
	     Go ahead and split them too.  This matches the logic in
	     gimple_find_edge_insert_loc.  */
	  else if (for_edge_insertion_p
		   && (!single_pred_p (e->dest)
		       || !gimple_seq_empty_p (phi_nodes (e->dest))
		       || e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
		   && e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun)
		   && !(e->flags & EDGE_ABNORMAL))
	    {
	      gimple_stmt_iterator gsi;

	      gsi = gsi_last_bb (e->src);
	      if (!gsi_end_p (gsi)
		  && stmt_ends_bb_p (gsi_stmt (gsi))
		  && (gimple_code (gsi_stmt (gsi)) != GIMPLE_RETURN
		      && !gimple_call_builtin_p (gsi_stmt (gsi),
						 BUILT_IN_RETURN)))
		split_edge (e);
	    }
	}
    }
  end_recording_case_labels ();
  return 0;
}

namespace {

const pass_data pass_data_split_crit_edges =
{
  GIMPLE_PASS, /* type */
  "crited", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_TREE_SPLIT_EDGES, /* tv_id */
  PROP_cfg, /* properties_required */
  PROP_no_crit_edges, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_split_crit_edges : public gimple_opt_pass
{
public:
  pass_split_crit_edges (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_split_crit_edges, ctxt)
  {}

  /* opt_pass methods: */
  unsigned int execute (function *)  final override
  {
    return split_critical_edges ();
  }

  opt_pass * clone () final override
  {
    return new pass_split_crit_edges (m_ctxt);
  }
}; // class pass_split_crit_edges

} // anon namespace

gimple_opt_pass *
make_pass_split_crit_edges (gcc::context *ctxt)
{
  return new pass_split_crit_edges (ctxt);
}


/* Insert COND expression which is GIMPLE_COND after STMT
   in basic block BB with appropriate basic block split
   and creation of a new conditionally executed basic block.
   Update profile so the new bb is visited with probability PROB.
   Return created basic block.  */
basic_block
insert_cond_bb (basic_block bb, gimple *stmt, gimple *cond,
	        profile_probability prob)
{
  edge fall = split_block (bb, stmt);
  gimple_stmt_iterator iter = gsi_last_bb (bb);
  basic_block new_bb;

  /* Insert cond statement.  */
  gcc_assert (gimple_code (cond) == GIMPLE_COND);
  if (gsi_end_p (iter))
    gsi_insert_before (&iter, cond, GSI_CONTINUE_LINKING);
  else
    gsi_insert_after (&iter, cond, GSI_CONTINUE_LINKING);

  /* Create conditionally executed block.  */
  new_bb = create_empty_bb (bb);
  edge e = make_edge (bb, new_bb, EDGE_TRUE_VALUE);
  e->probability = prob;
  new_bb->count = e->count ();
  make_single_succ_edge (new_bb, fall->dest, EDGE_FALLTHRU);

  /* Fix edge for split bb.  */
  fall->flags = EDGE_FALSE_VALUE;
  fall->probability -= e->probability;

  /* Update dominance info.  */
  if (dom_info_available_p (CDI_DOMINATORS))
    {
      set_immediate_dominator (CDI_DOMINATORS, new_bb, bb);
      set_immediate_dominator (CDI_DOMINATORS, fall->dest, bb);
    }

  /* Update loop info.  */
  if (current_loops)
    add_bb_to_loop (new_bb, bb->loop_father);

  return new_bb;
}



/* Given a basic block B which ends with a conditional and has
   precisely two successors, determine which of the edges is taken if
   the conditional is true and which is taken if the conditional is
   false.  Set TRUE_EDGE and FALSE_EDGE appropriately.  */

void
extract_true_false_edges_from_block (basic_block b,
				     edge *true_edge,
				     edge *false_edge)
{
  edge e = EDGE_SUCC (b, 0);

  if (e->flags & EDGE_TRUE_VALUE)
    {
      *true_edge = e;
      *false_edge = EDGE_SUCC (b, 1);
    }
  else
    {
      *false_edge = e;
      *true_edge = EDGE_SUCC (b, 1);
    }
}


/* From a controlling predicate in the immediate dominator DOM of
   PHIBLOCK determine the edges into PHIBLOCK that are chosen if the
   predicate evaluates to true and false and store them to
   *TRUE_CONTROLLED_EDGE and *FALSE_CONTROLLED_EDGE if
   they are non-NULL.  Returns true if the edges can be determined,
   else return false.  */

bool
extract_true_false_controlled_edges (basic_block dom, basic_block phiblock,
				     edge *true_controlled_edge,
				     edge *false_controlled_edge)
{
  basic_block bb = phiblock;
  edge true_edge, false_edge, tem;
  edge e0 = NULL, e1 = NULL;

  /* We have to verify that one edge into the PHI node is dominated
     by the true edge of the predicate block and the other edge
     dominated by the false edge.  This ensures that the PHI argument
     we are going to take is completely determined by the path we
     take from the predicate block.
     We can only use BB dominance checks below if the destination of
     the true/false edges are dominated by their edge, thus only
     have a single predecessor.  */
  extract_true_false_edges_from_block (dom, &true_edge, &false_edge);
  tem = EDGE_PRED (bb, 0);
  if (tem == true_edge
      || (single_pred_p (true_edge->dest)
	  && (tem->src == true_edge->dest
	      || dominated_by_p (CDI_DOMINATORS,
				 tem->src, true_edge->dest))))
    e0 = tem;
  else if (tem == false_edge
	   || (single_pred_p (false_edge->dest)
	       && (tem->src == false_edge->dest
		   || dominated_by_p (CDI_DOMINATORS,
				      tem->src, false_edge->dest))))
    e1 = tem;
  else
    return false;
  tem = EDGE_PRED (bb, 1);
  if (tem == true_edge
      || (single_pred_p (true_edge->dest)
	  && (tem->src == true_edge->dest
	      || dominated_by_p (CDI_DOMINATORS,
				 tem->src, true_edge->dest))))
    e0 = tem;
  else if (tem == false_edge
	   || (single_pred_p (false_edge->dest)
	       && (tem->src == false_edge->dest
		   || dominated_by_p (CDI_DOMINATORS,
				      tem->src, false_edge->dest))))
    e1 = tem;
  else
    return false;
  if (!e0 || !e1)
    return false;

  if (true_controlled_edge)
    *true_controlled_edge = e0;
  if (false_controlled_edge)
    *false_controlled_edge = e1;

  return true;
}

/* Generate a range test LHS CODE RHS that determines whether INDEX is in the
    range [low, high].  Place associated stmts before *GSI.  */

void
generate_range_test (basic_block bb, tree index, tree low, tree high,
		     tree *lhs, tree *rhs)
{
  tree type = TREE_TYPE (index);
  tree utype = range_check_type (type);

  low = fold_convert (utype, low);
  high = fold_convert (utype, high);

  gimple_seq seq = NULL;
  index = gimple_convert (&seq, utype, index);
  *lhs = gimple_build (&seq, MINUS_EXPR, utype, index, low);
  *rhs = const_binop (MINUS_EXPR, utype, high, low);

  gimple_stmt_iterator gsi = gsi_last_bb (bb);
  gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
}

/* Return the basic block that belongs to label numbered INDEX
   of a switch statement.  */

basic_block
gimple_switch_label_bb (function *ifun, gswitch *gs, unsigned index)
{
  return label_to_block (ifun, CASE_LABEL (gimple_switch_label (gs, index)));
}

/* Return the default basic block of a switch statement.  */

basic_block
gimple_switch_default_bb (function *ifun, gswitch *gs)
{
  return gimple_switch_label_bb (ifun, gs, 0);
}

/* Return the edge that belongs to label numbered INDEX
   of a switch statement.  */

edge
gimple_switch_edge (function *ifun, gswitch *gs, unsigned index)
{
  return find_edge (gimple_bb (gs), gimple_switch_label_bb (ifun, gs, index));
}

/* Return the default edge of a switch statement.  */

edge
gimple_switch_default_edge (function *ifun, gswitch *gs)
{
  return gimple_switch_edge (ifun, gs, 0);
}

/* Return true if the only executable statement in BB is a GIMPLE_COND.  */

bool
cond_only_block_p (basic_block bb)
{
  /* BB must have no executable statements.  */
  gimple_stmt_iterator gsi = gsi_after_labels (bb);
  if (phi_nodes (bb))
    return false;
  while (!gsi_end_p (gsi))
    {
      gimple *stmt = gsi_stmt (gsi);
      if (is_gimple_debug (stmt))
	;
      else if (gimple_code (stmt) == GIMPLE_NOP
	       || gimple_code (stmt) == GIMPLE_PREDICT
	       || gimple_code (stmt) == GIMPLE_COND)
	;
      else
	return false;
      gsi_next (&gsi);
    }
  return true;
}


/* Emit return warnings.  */

namespace {

const pass_data pass_data_warn_function_return =
{
  GIMPLE_PASS, /* type */
  "*warn_function_return", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_NONE, /* tv_id */
  PROP_cfg, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_warn_function_return : public gimple_opt_pass
{
public:
  pass_warn_function_return (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_warn_function_return, ctxt)
  {}

  /* opt_pass methods: */
  unsigned int execute (function *) final override;

}; // class pass_warn_function_return

unsigned int
pass_warn_function_return::execute (function *fun)
{
  location_t location;
  gimple *last;
  edge e;
  edge_iterator ei;

  if (!targetm.warn_func_return (fun->decl))
    return 0;

  /* If we have a path to EXIT, then we do return.  */
  if (TREE_THIS_VOLATILE (fun->decl)
      && EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (fun)->preds) > 0)
    {
      location = UNKNOWN_LOCATION;
      for (ei = ei_start (EXIT_BLOCK_PTR_FOR_FN (fun)->preds);
	   (e = ei_safe_edge (ei)); )
	{
	  last = last_stmt (e->src);
	  if ((gimple_code (last) == GIMPLE_RETURN
	       || gimple_call_builtin_p (last, BUILT_IN_RETURN))
	      && location == UNKNOWN_LOCATION
	      && ((location = LOCATION_LOCUS (gimple_location (last)))
		  != UNKNOWN_LOCATION)
	      && !optimize)
	    break;
	  /* When optimizing, replace return stmts in noreturn functions
	     with __builtin_unreachable () call.  */
	  if (optimize && gimple_code (last) == GIMPLE_RETURN)
	    {
	      location_t loc = gimple_location (last);
	      gimple *new_stmt = gimple_build_builtin_unreachable (loc);
	      gimple_stmt_iterator gsi = gsi_for_stmt (last);
	      gsi_replace (&gsi, new_stmt, true);
	      remove_edge (e);
	    }
	  else
	    ei_next (&ei);
	}
      if (location == UNKNOWN_LOCATION)
	location = cfun->function_end_locus;
      warning_at (location, 0, "%<noreturn%> function does return");
    }

  /* If we see "return;" in some basic block, then we do reach the end
     without returning a value.  */
  else if (warn_return_type > 0
	   && !warning_suppressed_p (fun->decl, OPT_Wreturn_type)
	   && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fun->decl))))
    {
      FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (fun)->preds)
	{
	  gimple *last = last_stmt (e->src);
	  greturn *return_stmt = dyn_cast <greturn *> (last);
	  if (return_stmt
	      && gimple_return_retval (return_stmt) == NULL
	      && !warning_suppressed_p (last, OPT_Wreturn_type))
	    {
	      location = gimple_location (last);
	      if (LOCATION_LOCUS (location) == UNKNOWN_LOCATION)
		location = fun->function_end_locus;
	      if (warning_at (location, OPT_Wreturn_type,
			      "control reaches end of non-void function"))
		suppress_warning (fun->decl, OPT_Wreturn_type);
	      break;
	    }
	}
      /* The C++ FE turns fallthrough from the end of non-void function
	 into __builtin_unreachable () call with BUILTINS_LOCATION.
	 Recognize those as well as calls from ubsan_instrument_return.  */
      basic_block bb;
      if (!warning_suppressed_p (fun->decl, OPT_Wreturn_type))
	FOR_EACH_BB_FN (bb, fun)
	  if (EDGE_COUNT (bb->succs) == 0)
	    {
	      gimple *last = last_stmt (bb);
	      const enum built_in_function ubsan_missing_ret
		= BUILT_IN_UBSAN_HANDLE_MISSING_RETURN;
	      if (last
		  && ((LOCATION_LOCUS (gimple_location (last))
		       == BUILTINS_LOCATION
		       && (gimple_call_builtin_p (last, BUILT_IN_UNREACHABLE)
			   || gimple_call_builtin_p (last, BUILT_IN_TRAP)))
		      || gimple_call_builtin_p (last, ubsan_missing_ret)))
		{
		  gimple_stmt_iterator gsi = gsi_for_stmt (last);
		  gsi_prev_nondebug (&gsi);
		  gimple *prev = gsi_stmt (gsi);
		  if (prev == NULL)
		    location = UNKNOWN_LOCATION;
		  else
		    location = gimple_location (prev);
		  if (LOCATION_LOCUS (location) == UNKNOWN_LOCATION)
		    location = fun->function_end_locus;
		  if (warning_at (location, OPT_Wreturn_type,
				  "control reaches end of non-void function"))
		    suppress_warning (fun->decl, OPT_Wreturn_type);
		  break;
		}
	    }
    }
  return 0;
}

} // anon namespace

gimple_opt_pass *
make_pass_warn_function_return (gcc::context *ctxt)
{
  return new pass_warn_function_return (ctxt);
}

/* Walk a gimplified function and warn for functions whose return value is
   ignored and attribute((warn_unused_result)) is set.  This is done before
   inlining, so we don't have to worry about that.  */

static void
do_warn_unused_result (gimple_seq seq)
{
  tree fdecl, ftype;
  gimple_stmt_iterator i;

  for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
    {
      gimple *g = gsi_stmt (i);

      switch (gimple_code (g))
	{
	case GIMPLE_BIND:
	  do_warn_unused_result (gimple_bind_body (as_a <gbind *>(g)));
	  break;
	case GIMPLE_TRY:
	  do_warn_unused_result (gimple_try_eval (g));
	  do_warn_unused_result (gimple_try_cleanup (g));
	  break;
	case GIMPLE_CATCH:
	  do_warn_unused_result (gimple_catch_handler (
				   as_a <gcatch *> (g)));
	  break;
	case GIMPLE_EH_FILTER:
	  do_warn_unused_result (gimple_eh_filter_failure (g));
	  break;

	case GIMPLE_CALL:
	  if (gimple_call_lhs (g))
	    break;
	  if (gimple_call_internal_p (g))
	    break;

	  /* This is a naked call, as opposed to a GIMPLE_CALL with an
	     LHS.  All calls whose value is ignored should be
	     represented like this.  Look for the attribute.  */
	  fdecl = gimple_call_fndecl (g);
	  ftype = gimple_call_fntype (g);

	  if (lookup_attribute ("warn_unused_result", TYPE_ATTRIBUTES (ftype)))
	    {
	      location_t loc = gimple_location (g);

	      if (fdecl)
		warning_at (loc, OPT_Wunused_result,
			    "ignoring return value of %qD "
			    "declared with attribute %<warn_unused_result%>",
			    fdecl);
	      else
		warning_at (loc, OPT_Wunused_result,
			    "ignoring return value of function "
			    "declared with attribute %<warn_unused_result%>");
	    }
	  break;

	default:
	  /* Not a container, not a call, or a call whose value is used.  */
	  break;
	}
    }
}

namespace {

const pass_data pass_data_warn_unused_result =
{
  GIMPLE_PASS, /* type */
  "*warn_unused_result", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_NONE, /* tv_id */
  PROP_gimple_any, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_warn_unused_result : public gimple_opt_pass
{
public:
  pass_warn_unused_result (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_warn_unused_result, ctxt)
  {}

  /* opt_pass methods: */
  bool gate (function *)  final override { return flag_warn_unused_result; }
  unsigned int execute (function *) final override
    {
      do_warn_unused_result (gimple_body (current_function_decl));
      return 0;
    }

}; // class pass_warn_unused_result

} // anon namespace

gimple_opt_pass *
make_pass_warn_unused_result (gcc::context *ctxt)
{
  return new pass_warn_unused_result (ctxt);
}

/* Maybe Remove stores to variables we marked write-only.
   Return true if a store was removed. */
static bool
maybe_remove_writeonly_store (gimple_stmt_iterator &gsi, gimple *stmt,
			      bitmap dce_ssa_names)
{
  /* Keep access when store has side effect, i.e. in case when source
     is volatile.  */  
  if (!gimple_store_p (stmt)
      || gimple_has_side_effects (stmt)
      || optimize_debug)
    return false;

  tree lhs = get_base_address (gimple_get_lhs (stmt));

  if (!VAR_P (lhs)
      || (!TREE_STATIC (lhs) && !DECL_EXTERNAL (lhs))
      || !varpool_node::get (lhs)->writeonly)
    return false;

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Removing statement, writes"
	       " to write only var:\n");
      print_gimple_stmt (dump_file, stmt, 0,
			 TDF_VOPS|TDF_MEMSYMS);
    }

  /* Mark ssa name defining to be checked for simple dce. */
  if (gimple_assign_single_p (stmt))
    {
      tree rhs = gimple_assign_rhs1 (stmt);
      if (TREE_CODE (rhs) == SSA_NAME
	  && !SSA_NAME_IS_DEFAULT_DEF (rhs))
	bitmap_set_bit (dce_ssa_names, SSA_NAME_VERSION (rhs));
    }
  unlink_stmt_vdef (stmt);
  gsi_remove (&gsi, true);
  release_defs (stmt);
  return true;
}

/* IPA passes, compilation of earlier functions or inlining
   might have changed some properties, such as marked functions nothrow,
   pure, const or noreturn.
   Remove redundant edges and basic blocks, and create new ones if necessary. */

unsigned int
execute_fixup_cfg (void)
{
  basic_block bb;
  gimple_stmt_iterator gsi;
  int todo = 0;
  cgraph_node *node = cgraph_node::get (current_function_decl);
  /* Same scaling is also done by ipa_merge_profiles.  */
  profile_count num = node->count;
  profile_count den = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count;
  bool scale = num.initialized_p () && !(num == den);
  auto_bitmap dce_ssa_names;

  if (scale)
    {
      profile_count::adjust_for_ipa_scaling (&num, &den);
      ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = node->count;
      EXIT_BLOCK_PTR_FOR_FN (cfun)->count
        = EXIT_BLOCK_PTR_FOR_FN (cfun)->count.apply_scale (num, den);
    }

  FOR_EACH_BB_FN (bb, cfun)
    {
      if (scale)
        bb->count = bb->count.apply_scale (num, den);
      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
	{
	  gimple *stmt = gsi_stmt (gsi);
	  tree decl = is_gimple_call (stmt)
		      ? gimple_call_fndecl (stmt)
		      : NULL;
	  if (decl)
	    {
	      int flags = gimple_call_flags (stmt);
	      if (flags & (ECF_CONST | ECF_PURE | ECF_LOOPING_CONST_OR_PURE))
		{
		  if (gimple_in_ssa_p (cfun))
		    {
		      todo |= TODO_update_ssa | TODO_cleanup_cfg;
		      update_stmt (stmt);
		    }
		}
	      if (flags & ECF_NORETURN
		  && fixup_noreturn_call (stmt))
		todo |= TODO_cleanup_cfg;
	     }

	  /* Remove stores to variables we marked write-only. */
	  if (maybe_remove_writeonly_store (gsi, stmt, dce_ssa_names))
	    {
	      todo |= TODO_update_ssa | TODO_cleanup_cfg;
	      continue;
	    }

	  /* For calls we can simply remove LHS when it is known
	     to be write-only.  */
	  if (is_gimple_call (stmt)
	      && gimple_get_lhs (stmt))
	    {
	      tree lhs = get_base_address (gimple_get_lhs (stmt));

	      if (VAR_P (lhs)
		  && (TREE_STATIC (lhs) || DECL_EXTERNAL (lhs))
		  && varpool_node::get (lhs)->writeonly)
		{
		  gimple_call_set_lhs (stmt, NULL);
		  update_stmt (stmt);
	          todo |= TODO_update_ssa | TODO_cleanup_cfg;
		}
	    }

	  gsi_next (&gsi);
	}
      if (gimple *last = last_stmt (bb))
	{
	  if (maybe_clean_eh_stmt (last)
	      && gimple_purge_dead_eh_edges (bb))
	    todo |= TODO_cleanup_cfg;
	  if (gimple_purge_dead_abnormal_call_edges (bb))
	    todo |= TODO_cleanup_cfg;
	}

      /* If we have a basic block with no successors that does not
	 end with a control statement or a noreturn call end it with
	 a call to __builtin_unreachable.  This situation can occur
	 when inlining a noreturn call that does in fact return.  */
      if (EDGE_COUNT (bb->succs) == 0)
	{
	  gimple *stmt = last_stmt (bb);
	  if (!stmt
	      || (!is_ctrl_stmt (stmt)
		  && (!is_gimple_call (stmt)
		      || !gimple_call_noreturn_p (stmt))))
	    {
	      if (stmt && is_gimple_call (stmt))
		gimple_call_set_ctrl_altering (stmt, false);
	      stmt = gimple_build_builtin_unreachable (UNKNOWN_LOCATION);
	      gimple_stmt_iterator gsi = gsi_last_bb (bb);
	      gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
	      if (!cfun->after_inlining)
		if (tree fndecl = gimple_call_fndecl (stmt))
		  {
		    gcall *call_stmt = dyn_cast <gcall *> (stmt);
		    node->create_edge (cgraph_node::get_create (fndecl),
				       call_stmt, bb->count);
		  }
	    }
	}
    }
  if (scale)
    {
      update_max_bb_count ();
      compute_function_frequency ();
    }

  if (current_loops
      && (todo & TODO_cleanup_cfg))
    loops_state_set (LOOPS_NEED_FIXUP);

  simple_dce_from_worklist (dce_ssa_names);

  return todo;
}

namespace {

const pass_data pass_data_fixup_cfg =
{
  GIMPLE_PASS, /* type */
  "fixup_cfg", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_NONE, /* tv_id */
  PROP_cfg, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_fixup_cfg : public gimple_opt_pass
{
public:
  pass_fixup_cfg (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_fixup_cfg, ctxt)
  {}

  /* opt_pass methods: */
  opt_pass * clone () final override { return new pass_fixup_cfg (m_ctxt); }
  unsigned int execute (function *) final override
  {
    return execute_fixup_cfg ();
  }

}; // class pass_fixup_cfg

} // anon namespace

gimple_opt_pass *
make_pass_fixup_cfg (gcc::context *ctxt)
{
  return new pass_fixup_cfg (ctxt);
}

/* Garbage collection support for edge_def.  */

extern void gt_ggc_mx (tree&);
extern void gt_ggc_mx (gimple *&);
extern void gt_ggc_mx (rtx&);
extern void gt_ggc_mx (basic_block&);

static void
gt_ggc_mx (rtx_insn *& x)
{
  if (x)
    gt_ggc_mx_rtx_def ((void *) x);
}

void
gt_ggc_mx (edge_def *e)
{
  tree block = LOCATION_BLOCK (e->goto_locus);
  gt_ggc_mx (e->src);
  gt_ggc_mx (e->dest);
  if (current_ir_type () == IR_GIMPLE)
    gt_ggc_mx (e->insns.g);
  else
    gt_ggc_mx (e->insns.r);
  gt_ggc_mx (block);
}

/* PCH support for edge_def.  */

extern void gt_pch_nx (tree&);
extern void gt_pch_nx (gimple *&);
extern void gt_pch_nx (rtx&);
extern void gt_pch_nx (basic_block&);

static void
gt_pch_nx (rtx_insn *& x)
{
  if (x)
    gt_pch_nx_rtx_def ((void *) x);
}

void
gt_pch_nx (edge_def *e)
{
  tree block = LOCATION_BLOCK (e->goto_locus);
  gt_pch_nx (e->src);
  gt_pch_nx (e->dest);
  if (current_ir_type () == IR_GIMPLE)
    gt_pch_nx (e->insns.g);
  else
    gt_pch_nx (e->insns.r);
  gt_pch_nx (block);
}

void
gt_pch_nx (edge_def *e, gt_pointer_operator op, void *cookie)
{
  tree block = LOCATION_BLOCK (e->goto_locus);
  op (&(e->src), NULL, cookie);
  op (&(e->dest), NULL, cookie);
  if (current_ir_type () == IR_GIMPLE)
    op (&(e->insns.g), NULL, cookie);
  else
    op (&(e->insns.r), NULL, cookie);
  op (&(block), &(block), cookie);
}

#if CHECKING_P

namespace selftest {

/* Helper function for CFG selftests: create a dummy function decl
   and push it as cfun.  */

static tree
push_fndecl (const char *name)
{
  tree fn_type = build_function_type_array (integer_type_node, 0, NULL);
  /* FIXME: this uses input_location: */
  tree fndecl = build_fn_decl (name, fn_type);
  tree retval = build_decl (UNKNOWN_LOCATION, RESULT_DECL,
			    NULL_TREE, integer_type_node);
  DECL_RESULT (fndecl) = retval;
  push_struct_function (fndecl);
  function *fun = DECL_STRUCT_FUNCTION (fndecl);
  ASSERT_TRUE (fun != NULL);
  init_empty_tree_cfg_for_function (fun);
  ASSERT_EQ (2, n_basic_blocks_for_fn (fun));
  ASSERT_EQ (0, n_edges_for_fn (fun));
  return fndecl;
}

/* These tests directly create CFGs.
   Compare with the static fns within tree-cfg.cc:
     - build_gimple_cfg
     - make_blocks: calls create_basic_block (seq, bb);
     - make_edges.   */

/* Verify a simple cfg of the form:
     ENTRY -> A -> B -> C -> EXIT.  */

static void
test_linear_chain ()
{
  gimple_register_cfg_hooks ();

  tree fndecl = push_fndecl ("cfg_test_linear_chain");
  function *fun = DECL_STRUCT_FUNCTION (fndecl);

  /* Create some empty blocks.  */
  basic_block bb_a = create_empty_bb (ENTRY_BLOCK_PTR_FOR_FN (fun));
  basic_block bb_b = create_empty_bb (bb_a);
  basic_block bb_c = create_empty_bb (bb_b);

  ASSERT_EQ (5, n_basic_blocks_for_fn (fun));
  ASSERT_EQ (0, n_edges_for_fn (fun));

  /* Create some edges: a simple linear chain of BBs.  */
  make_edge (ENTRY_BLOCK_PTR_FOR_FN (fun), bb_a, EDGE_FALLTHRU);
  make_edge (bb_a, bb_b, 0);
  make_edge (bb_b, bb_c, 0);
  make_edge (bb_c, EXIT_BLOCK_PTR_FOR_FN (fun), 0);

  /* Verify the edges.  */
  ASSERT_EQ (4, n_edges_for_fn (fun));
  ASSERT_EQ (NULL, ENTRY_BLOCK_PTR_FOR_FN (fun)->preds);
  ASSERT_EQ (1, ENTRY_BLOCK_PTR_FOR_FN (fun)->succs->length ());
  ASSERT_EQ (1, bb_a->preds->length ());
  ASSERT_EQ (1, bb_a->succs->length ());
  ASSERT_EQ (1, bb_b->preds->length ());
  ASSERT_EQ (1, bb_b->succs->length ());
  ASSERT_EQ (1, bb_c->preds->length ());
  ASSERT_EQ (1, bb_c->succs->length ());
  ASSERT_EQ (1, EXIT_BLOCK_PTR_FOR_FN (fun)->preds->length ());
  ASSERT_EQ (NULL, EXIT_BLOCK_PTR_FOR_FN (fun)->succs);

  /* Verify the dominance information
     Each BB in our simple chain should be dominated by the one before
     it.  */
  calculate_dominance_info (CDI_DOMINATORS);
  ASSERT_EQ (bb_a, get_immediate_dominator (CDI_DOMINATORS, bb_b));
  ASSERT_EQ (bb_b, get_immediate_dominator (CDI_DOMINATORS, bb_c));
  auto_vec<basic_block> dom_by_b = get_dominated_by (CDI_DOMINATORS, bb_b);
  ASSERT_EQ (1, dom_by_b.length ());
  ASSERT_EQ (bb_c, dom_by_b[0]);
  free_dominance_info (CDI_DOMINATORS);

  /* Similarly for post-dominance: each BB in our chain is post-dominated
     by the one after it.  */
  calculate_dominance_info (CDI_POST_DOMINATORS);
  ASSERT_EQ (bb_b, get_immediate_dominator (CDI_POST_DOMINATORS, bb_a));
  ASSERT_EQ (bb_c, get_immediate_dominator (CDI_POST_DOMINATORS, bb_b));
  auto_vec<basic_block> postdom_by_b = get_dominated_by (CDI_POST_DOMINATORS, bb_b);
  ASSERT_EQ (1, postdom_by_b.length ());
  ASSERT_EQ (bb_a, postdom_by_b[0]);
  free_dominance_info (CDI_POST_DOMINATORS);

  pop_cfun ();
}

/* Verify a simple CFG of the form:
     ENTRY
       |
       A
      / \
     /t  \f
    B     C
     \   /
      \ /
       D
       |
      EXIT.  */

static void
test_diamond ()
{
  gimple_register_cfg_hooks ();

  tree fndecl = push_fndecl ("cfg_test_diamond");
  function *fun = DECL_STRUCT_FUNCTION (fndecl);

  /* Create some empty blocks.  */
  basic_block bb_a = create_empty_bb (ENTRY_BLOCK_PTR_FOR_FN (fun));
  basic_block bb_b = create_empty_bb (bb_a);
  basic_block bb_c = create_empty_bb (bb_a);
  basic_block bb_d = create_empty_bb (bb_b);

  ASSERT_EQ (6, n_basic_blocks_for_fn (fun));
  ASSERT_EQ (0, n_edges_for_fn (fun));

  /* Create the edges.  */
  make_edge (ENTRY_BLOCK_PTR_FOR_FN (fun), bb_a, EDGE_FALLTHRU);
  make_edge (bb_a, bb_b, EDGE_TRUE_VALUE);
  make_edge (bb_a, bb_c, EDGE_FALSE_VALUE);
  make_edge (bb_b, bb_d, 0);
  make_edge (bb_c, bb_d, 0);
  make_edge (bb_d, EXIT_BLOCK_PTR_FOR_FN (fun), 0);

  /* Verify the edges.  */
  ASSERT_EQ (6, n_edges_for_fn (fun));
  ASSERT_EQ (1, bb_a->preds->length ());
  ASSERT_EQ (2, bb_a->succs->length ());
  ASSERT_EQ (1, bb_b->preds->length ());
  ASSERT_EQ (1, bb_b->succs->length ());
  ASSERT_EQ (1, bb_c->preds->length ());
  ASSERT_EQ (1, bb_c->succs->length ());
  ASSERT_EQ (2, bb_d->preds->length ());
  ASSERT_EQ (1, bb_d->succs->length ());

  /* Verify the dominance information.  */
  calculate_dominance_info (CDI_DOMINATORS);
  ASSERT_EQ (bb_a, get_immediate_dominator (CDI_DOMINATORS, bb_b));
  ASSERT_EQ (bb_a, get_immediate_dominator (CDI_DOMINATORS, bb_c));
  ASSERT_EQ (bb_a, get_immediate_dominator (CDI_DOMINATORS, bb_d));
  auto_vec<basic_block> dom_by_a = get_dominated_by (CDI_DOMINATORS, bb_a);
  ASSERT_EQ (3, dom_by_a.length ()); /* B, C, D, in some order.  */
  dom_by_a.release ();
  auto_vec<basic_block> dom_by_b = get_dominated_by (CDI_DOMINATORS, bb_b);
  ASSERT_EQ (0, dom_by_b.length ());
  dom_by_b.release ();
  free_dominance_info (CDI_DOMINATORS);

  /* Similarly for post-dominance.  */
  calculate_dominance_info (CDI_POST_DOMINATORS);
  ASSERT_EQ (bb_d, get_immediate_dominator (CDI_POST_DOMINATORS, bb_a));
  ASSERT_EQ (bb_d, get_immediate_dominator (CDI_POST_DOMINATORS, bb_b));
  ASSERT_EQ (bb_d, get_immediate_dominator (CDI_POST_DOMINATORS, bb_c));
  auto_vec<basic_block> postdom_by_d = get_dominated_by (CDI_POST_DOMINATORS, bb_d);
  ASSERT_EQ (3, postdom_by_d.length ()); /* A, B, C in some order.  */
  postdom_by_d.release ();
  auto_vec<basic_block> postdom_by_b = get_dominated_by (CDI_POST_DOMINATORS, bb_b);
  ASSERT_EQ (0, postdom_by_b.length ());
  postdom_by_b.release ();
  free_dominance_info (CDI_POST_DOMINATORS);

  pop_cfun ();
}

/* Verify that we can handle a CFG containing a "complete" aka
   fully-connected subgraph (where A B C D below all have edges
   pointing to each other node, also to themselves).
   e.g.:
     ENTRY  EXIT
       |    ^
       |   /
       |  /
       | /
       V/
       A<--->B
       ^^   ^^
       | \ / |
       |  X  |
       | / \ |
       VV   VV
       C<--->D
*/

static void
test_fully_connected ()
{
  gimple_register_cfg_hooks ();

  tree fndecl = push_fndecl ("cfg_fully_connected");
  function *fun = DECL_STRUCT_FUNCTION (fndecl);

  const int n = 4;

  /* Create some empty blocks.  */
  auto_vec <basic_block> subgraph_nodes;
  for (int i = 0; i < n; i++)
    subgraph_nodes.safe_push (create_empty_bb (ENTRY_BLOCK_PTR_FOR_FN (fun)));

  ASSERT_EQ (n + 2, n_basic_blocks_for_fn (fun));
  ASSERT_EQ (0, n_edges_for_fn (fun));

  /* Create the edges.  */
  make_edge (ENTRY_BLOCK_PTR_FOR_FN (fun), subgraph_nodes[0], EDGE_FALLTHRU);
  make_edge (subgraph_nodes[0], EXIT_BLOCK_PTR_FOR_FN (fun), 0);
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++)
      make_edge (subgraph_nodes[i], subgraph_nodes[j], 0);

  /* Verify the edges.  */
  ASSERT_EQ (2 + (n * n), n_edges_for_fn (fun));
  /* The first one is linked to ENTRY/EXIT as well as itself and
     everything else.  */
  ASSERT_EQ (n + 1, subgraph_nodes[0]->preds->length ());
  ASSERT_EQ (n + 1, subgraph_nodes[0]->succs->length ());
  /* The other ones in the subgraph are linked to everything in
     the subgraph (including themselves).  */
  for (int i = 1; i < n; i++)
    {
      ASSERT_EQ (n, subgraph_nodes[i]->preds->length ());
      ASSERT_EQ (n, subgraph_nodes[i]->succs->length ());
    }

  /* Verify the dominance information.  */
  calculate_dominance_info (CDI_DOMINATORS);
  /* The initial block in the subgraph should be dominated by ENTRY.  */
  ASSERT_EQ (ENTRY_BLOCK_PTR_FOR_FN (fun),
	     get_immediate_dominator (CDI_DOMINATORS,
				      subgraph_nodes[0]));
  /* Every other block in the subgraph should be dominated by the
     initial block.  */
  for (int i = 1; i < n; i++)
    ASSERT_EQ (subgraph_nodes[0],
	       get_immediate_dominator (CDI_DOMINATORS,
					subgraph_nodes[i]));
  free_dominance_info (CDI_DOMINATORS);

  /* Similarly for post-dominance.  */
  calculate_dominance_info (CDI_POST_DOMINATORS);
  /* The initial block in the subgraph should be postdominated by EXIT.  */
  ASSERT_EQ (EXIT_BLOCK_PTR_FOR_FN (fun),
	     get_immediate_dominator (CDI_POST_DOMINATORS,
				      subgraph_nodes[0]));
  /* Every other block in the subgraph should be postdominated by the
     initial block, since that leads to EXIT.  */
  for (int i = 1; i < n; i++)
    ASSERT_EQ (subgraph_nodes[0],
	       get_immediate_dominator (CDI_POST_DOMINATORS,
					subgraph_nodes[i]));
  free_dominance_info (CDI_POST_DOMINATORS);

  pop_cfun ();
}

/* Run all of the selftests within this file.  */

void
tree_cfg_cc_tests ()
{
  test_linear_chain ();
  test_diamond ();
  test_fully_connected ();
}

} // namespace selftest

/* TODO: test the dominator/postdominator logic with various graphs/nodes:
   - loop
   - nested loops
   - switch statement (a block with many out-edges)
   - something that jumps to itself
   - etc  */

#endif /* CHECKING_P */
