/* Thread edges through blocks and update the control flow and SSA graphs.
   Copyright (C) 2004-2021 Free Software Foundation, Inc.

This file is part of GCC.

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

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

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

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "gimple.h"
#include "cfghooks.h"
#include "tree-pass.h"
#include "ssa.h"
#include "fold-const.h"
#include "cfganal.h"
#include "gimple-iterator.h"
#include "tree-ssa.h"
#include "tree-ssa-threadupdate.h"
#include "cfgloop.h"
#include "dbgcnt.h"
#include "tree-cfg.h"
#include "tree-vectorizer.h"

/* Given a block B, update the CFG and SSA graph to reflect redirecting
   one or more in-edges to B to instead reach the destination of an
   out-edge from B while preserving any side effects in B.

   i.e., given A->B and B->C, change A->B to be A->C yet still preserve the
   side effects of executing B.

     1. Make a copy of B (including its outgoing edges and statements).  Call
	the copy B'.  Note B' has no incoming edges or PHIs at this time.

     2. Remove the control statement at the end of B' and all outgoing edges
	except B'->C.

     3. Add a new argument to each PHI in C with the same value as the existing
	argument associated with edge B->C.  Associate the new PHI arguments
	with the edge B'->C.

     4. For each PHI in B, find or create a PHI in B' with an identical
	PHI_RESULT.  Add an argument to the PHI in B' which has the same
	value as the PHI in B associated with the edge A->B.  Associate
	the new argument in the PHI in B' with the edge A->B.

     5. Change the edge A->B to A->B'.

	5a. This automatically deletes any PHI arguments associated with the
	    edge A->B in B.

	5b. This automatically associates each new argument added in step 4
	    with the edge A->B'.

     6. Repeat for other incoming edges into B.

     7. Put the duplicated resources in B and all the B' blocks into SSA form.

   Note that block duplication can be minimized by first collecting the
   set of unique destination blocks that the incoming edges should
   be threaded to.

   We reduce the number of edges and statements we create by not copying all
   the outgoing edges and the control statement in step #1.  We instead create
   a template block without the outgoing edges and duplicate the template.

   Another case this code handles is threading through a "joiner" block.  In
   this case, we do not know the destination of the joiner block, but one
   of the outgoing edges from the joiner block leads to a threadable path.  This
   case largely works as outlined above, except the duplicate of the joiner
   block still contains a full set of outgoing edges and its control statement.
   We just redirect one of its outgoing edges to our jump threading path.  */


/* Steps #5 and #6 of the above algorithm are best implemented by walking
   all the incoming edges which thread to the same destination edge at
   the same time.  That avoids lots of table lookups to get information
   for the destination edge.

   To realize that implementation we create a list of incoming edges
   which thread to the same outgoing edge.  Thus to implement steps
   #5 and #6 we traverse our hash table of outgoing edge information.
   For each entry we walk the list of incoming edges which thread to
   the current outgoing edge.  */

struct el
{
  edge e;
  struct el *next;
};

/* Main data structure recording information regarding B's duplicate
   blocks.  */

/* We need to efficiently record the unique thread destinations of this
   block and specific information associated with those destinations.  We
   may have many incoming edges threaded to the same outgoing edge.  This
   can be naturally implemented with a hash table.  */

struct redirection_data : free_ptr_hash<redirection_data>
{
  /* We support wiring up two block duplicates in a jump threading path.

     One is a normal block copy where we remove the control statement
     and wire up its single remaining outgoing edge to the thread path.

     The other is a joiner block where we leave the control statement
     in place, but wire one of the outgoing edges to a thread path.

     In theory we could have multiple block duplicates in a jump
     threading path, but I haven't tried that.

     The duplicate blocks appear in this array in the same order in
     which they appear in the jump thread path.  */
  basic_block dup_blocks[2];

  vec<jump_thread_edge *> *path;

  /* A list of incoming edges which we want to thread to the
     same path.  */
  struct el *incoming_edges;

  /* hash_table support.  */
  static inline hashval_t hash (const redirection_data *);
  static inline int equal (const redirection_data *, const redirection_data *);
};

jump_thread_path_allocator::jump_thread_path_allocator ()
{
  obstack_init (&m_obstack);
}

jump_thread_path_allocator::~jump_thread_path_allocator ()
{
  obstack_free (&m_obstack, NULL);
}

jump_thread_edge *
jump_thread_path_allocator::allocate_thread_edge (edge e,
						  jump_thread_edge_type type)
{
  void *r = obstack_alloc (&m_obstack, sizeof (jump_thread_edge));
  return new (r) jump_thread_edge (e, type);
}

vec<jump_thread_edge *> *
jump_thread_path_allocator::allocate_thread_path ()
{
  // ?? Since the paths live in an obstack, we should be able to remove all
  // references to path->release() throughout the code.
  void *r = obstack_alloc (&m_obstack, sizeof (vec <jump_thread_edge *>));
  return new (r) vec<jump_thread_edge *> ();
}

jump_thread_path_registry::jump_thread_path_registry ()
{
  m_paths.create (5);
  m_removed_edges = new hash_table<struct removed_edges> (17);
  m_num_threaded_edges = 0;
  m_redirection_data = NULL;
}

jump_thread_path_registry::~jump_thread_path_registry ()
{
  m_paths.release ();
  delete m_removed_edges;
}

jump_thread_edge *
jump_thread_path_registry::allocate_thread_edge (edge e,
						 jump_thread_edge_type t)
{
  return m_allocator.allocate_thread_edge (e, t);
}

vec<jump_thread_edge *> *
jump_thread_path_registry::allocate_thread_path ()
{
  return m_allocator.allocate_thread_path ();
}

/* Dump a jump threading path, including annotations about each
   edge in the path.  */

void
dump_jump_thread_path (FILE *dump_file,
		       const vec<jump_thread_edge *> path,
		       bool registering)
{
  fprintf (dump_file,
	   "  %s%s jump thread: (%d, %d) incoming edge; ",
	   (registering ? "Registering" : "Cancelling"),
	   (path[0]->type == EDGE_FSM_THREAD ? " FSM": ""),
	   path[0]->e->src->index, path[0]->e->dest->index);

  for (unsigned int i = 1; i < path.length (); i++)
    {
      /* We can get paths with a NULL edge when the final destination
	 of a jump thread turns out to be a constant address.  We dump
	 those paths when debugging, so we have to be prepared for that
	 possibility here.  */
      if (path[i]->e == NULL)
	continue;

      if (path[i]->type == EDGE_COPY_SRC_JOINER_BLOCK)
	fprintf (dump_file, " (%d, %d) joiner; ",
		 path[i]->e->src->index, path[i]->e->dest->index);
      if (path[i]->type == EDGE_COPY_SRC_BLOCK)
       fprintf (dump_file, " (%d, %d) normal;",
		 path[i]->e->src->index, path[i]->e->dest->index);
      if (path[i]->type == EDGE_NO_COPY_SRC_BLOCK)
       fprintf (dump_file, " (%d, %d) nocopy;",
		 path[i]->e->src->index, path[i]->e->dest->index);
      if (path[0]->type == EDGE_FSM_THREAD)
	fprintf (dump_file, " (%d, %d) ",
		 path[i]->e->src->index, path[i]->e->dest->index);
    }
  fputc ('\n', dump_file);
}

DEBUG_FUNCTION void
debug (const vec<jump_thread_edge *> &path)
{
  dump_jump_thread_path (stderr, path, true);
}

/* Simple hashing function.  For any given incoming edge E, we're going
   to be most concerned with the final destination of its jump thread
   path.  So hash on the block index of the final edge in the path.  */

inline hashval_t
redirection_data::hash (const redirection_data *p)
{
  vec<jump_thread_edge *> *path = p->path;
  return path->last ()->e->dest->index;
}

/* Given two hash table entries, return true if they have the same
   jump threading path.  */
inline int
redirection_data::equal (const redirection_data *p1, const redirection_data *p2)
{
  vec<jump_thread_edge *> *path1 = p1->path;
  vec<jump_thread_edge *> *path2 = p2->path;

  if (path1->length () != path2->length ())
    return false;

  for (unsigned int i = 1; i < path1->length (); i++)
    {
      if ((*path1)[i]->type != (*path2)[i]->type
	  || (*path1)[i]->e != (*path2)[i]->e)
	return false;
    }

  return true;
}

/* Data structure of information to pass to hash table traversal routines.  */
struct ssa_local_info_t
{
  /* The current block we are working on.  */
  basic_block bb;

  /* We only create a template block for the first duplicated block in a
     jump threading path as we may need many duplicates of that block.

     The second duplicate block in a path is specific to that path.  Creating
     and sharing a template for that block is considerably more difficult.  */
  basic_block template_block;

  /* If we append debug stmts to the template block after creating it,
     this iterator won't be the last one in the block, and further
     copies of the template block shouldn't get debug stmts after
     it.  */
  gimple_stmt_iterator template_last_to_copy;

  /* Blocks duplicated for the thread.  */
  bitmap duplicate_blocks;

  /* TRUE if we thread one or more jumps, FALSE otherwise.  */
  bool jumps_threaded;

  /* When we have multiple paths through a joiner which reach different
     final destinations, then we may need to correct for potential
     profile insanities.  */
  bool need_profile_correction;

  // Jump threading statistics.
  unsigned long num_threaded_edges;
};

/* When we start updating the CFG for threading, data necessary for jump
   threading is attached to the AUX field for the incoming edge.  Use these
   macros to access the underlying structure attached to the AUX field.  */
#define THREAD_PATH(E) ((vec<jump_thread_edge *> *)(E)->aux)

/* Remove the last statement in block BB if it is a control statement
   Also remove all outgoing edges except the edge which reaches DEST_BB.
   If DEST_BB is NULL, then remove all outgoing edges.  */

static void
remove_ctrl_stmt_and_useless_edges (basic_block bb, basic_block dest_bb)
{
  gimple_stmt_iterator gsi;
  edge e;
  edge_iterator ei;

  gsi = gsi_last_bb (bb);

  /* If the duplicate ends with a control statement, then remove it.

     Note that if we are duplicating the template block rather than the
     original basic block, then the duplicate might not have any real
     statements in it.  */
  if (!gsi_end_p (gsi)
      && gsi_stmt (gsi)
      && (gimple_code (gsi_stmt (gsi)) == GIMPLE_COND
	  || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
	  || gimple_code (gsi_stmt (gsi)) == GIMPLE_SWITCH))
    gsi_remove (&gsi, true);

  for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
    {
      if (e->dest != dest_bb)
	{
	  free_dom_edge_info (e);
	  remove_edge (e);
	}
      else
	{
	  e->probability = profile_probability::always ();
	  ei_next (&ei);
	}
    }

  /* If the remaining edge is a loop exit, there must have
     a removed edge that was not a loop exit.

     In that case BB and possibly other blocks were previously
     in the loop, but are now outside the loop.  Thus, we need
     to update the loop structures.  */
  if (single_succ_p (bb)
      && loop_outer (bb->loop_father)
      && loop_exit_edge_p (bb->loop_father, single_succ_edge (bb)))
    loops_state_set (LOOPS_NEED_FIXUP);
}

/* Create a duplicate of BB.  Record the duplicate block in an array
   indexed by COUNT stored in RD.  */

static void
create_block_for_threading (basic_block bb,
			    struct redirection_data *rd,
			    unsigned int count,
			    bitmap *duplicate_blocks)
{
  edge_iterator ei;
  edge e;

  /* We can use the generic block duplication code and simply remove
     the stuff we do not need.  */
  rd->dup_blocks[count] = duplicate_block (bb, NULL, NULL);

  FOR_EACH_EDGE (e, ei, rd->dup_blocks[count]->succs)
    {
      e->aux = NULL;

      /* If we duplicate a block with an outgoing edge marked as
	 EDGE_IGNORE, we must clear EDGE_IGNORE so that it doesn't
	 leak out of the current pass.

	 It would be better to simplify switch statements and remove
	 the edges before we get here, but the sequencing is nontrivial.  */
      e->flags &= ~EDGE_IGNORE;
    }

  /* Zero out the profile, since the block is unreachable for now.  */
  rd->dup_blocks[count]->count = profile_count::uninitialized ();
  if (duplicate_blocks)
    bitmap_set_bit (*duplicate_blocks, rd->dup_blocks[count]->index);
}

/* Given an outgoing edge E lookup and return its entry in our hash table.

   If INSERT is true, then we insert the entry into the hash table if
   it is not already present.  INCOMING_EDGE is added to the list of incoming
   edges associated with E in the hash table.  */

redirection_data *
jump_thread_path_registry::lookup_redirection_data (edge e,
						    enum insert_option insert)
{
  struct redirection_data **slot;
  struct redirection_data *elt;
  vec<jump_thread_edge *> *path = THREAD_PATH (e);

  /* Build a hash table element so we can see if E is already
     in the table.  */
  elt = XNEW (struct redirection_data);
  elt->path = path;
  elt->dup_blocks[0] = NULL;
  elt->dup_blocks[1] = NULL;
  elt->incoming_edges = NULL;

  slot = m_redirection_data->find_slot (elt, insert);

  /* This will only happen if INSERT is false and the entry is not
     in the hash table.  */
  if (slot == NULL)
    {
      free (elt);
      return NULL;
    }

  /* This will only happen if E was not in the hash table and
     INSERT is true.  */
  if (*slot == NULL)
    {
      *slot = elt;
      elt->incoming_edges = XNEW (struct el);
      elt->incoming_edges->e = e;
      elt->incoming_edges->next = NULL;
      return elt;
    }
  /* E was in the hash table.  */
  else
    {
      /* Free ELT as we do not need it anymore, we will extract the
	 relevant entry from the hash table itself.  */
      free (elt);

      /* Get the entry stored in the hash table.  */
      elt = *slot;

      /* If insertion was requested, then we need to add INCOMING_EDGE
	 to the list of incoming edges associated with E.  */
      if (insert)
	{
	  struct el *el = XNEW (struct el);
	  el->next = elt->incoming_edges;
	  el->e = e;
	  elt->incoming_edges = el;
	}

      return elt;
    }
}

/* Similar to copy_phi_args, except that the PHI arg exists, it just
   does not have a value associated with it.  */

static void
copy_phi_arg_into_existing_phi (edge src_e, edge tgt_e)
{
  int src_idx = src_e->dest_idx;
  int tgt_idx = tgt_e->dest_idx;

  /* Iterate over each PHI in e->dest.  */
  for (gphi_iterator gsi = gsi_start_phis (src_e->dest),
			   gsi2 = gsi_start_phis (tgt_e->dest);
       !gsi_end_p (gsi);
       gsi_next (&gsi), gsi_next (&gsi2))
    {
      gphi *src_phi = gsi.phi ();
      gphi *dest_phi = gsi2.phi ();
      tree val = gimple_phi_arg_def (src_phi, src_idx);
      location_t locus = gimple_phi_arg_location (src_phi, src_idx);

      SET_PHI_ARG_DEF (dest_phi, tgt_idx, val);
      gimple_phi_arg_set_location (dest_phi, tgt_idx, locus);
    }
}

/* Given ssa_name DEF, backtrack jump threading PATH from node IDX
   to see if it has constant value in a flow sensitive manner.  Set
   LOCUS to location of the constant phi arg and return the value.
   Return DEF directly if either PATH or idx is ZERO.  */

static tree
get_value_locus_in_path (tree def, vec<jump_thread_edge *> *path,
			 basic_block bb, int idx, location_t *locus)
{
  tree arg;
  gphi *def_phi;
  basic_block def_bb;

  if (path == NULL || idx == 0)
    return def;

  def_phi = dyn_cast <gphi *> (SSA_NAME_DEF_STMT (def));
  if (!def_phi)
    return def;

  def_bb = gimple_bb (def_phi);
  /* Don't propagate loop invariants into deeper loops.  */
  if (!def_bb || bb_loop_depth (def_bb) < bb_loop_depth (bb))
    return def;

  /* Backtrack jump threading path from IDX to see if def has constant
     value.  */
  for (int j = idx - 1; j >= 0; j--)
    {
      edge e = (*path)[j]->e;
      if (e->dest == def_bb)
	{
	  arg = gimple_phi_arg_def (def_phi, e->dest_idx);
	  if (is_gimple_min_invariant (arg))
	    {
	      *locus = gimple_phi_arg_location (def_phi, e->dest_idx);
	      return arg;
	    }
	  break;
	}
    }

  return def;
}

/* For each PHI in BB, copy the argument associated with SRC_E to TGT_E.
   Try to backtrack jump threading PATH from node IDX to see if the arg
   has constant value, copy constant value instead of argument itself
   if yes.  */

static void
copy_phi_args (basic_block bb, edge src_e, edge tgt_e,
	       vec<jump_thread_edge *> *path, int idx)
{
  gphi_iterator gsi;
  int src_indx = src_e->dest_idx;

  for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    {
      gphi *phi = gsi.phi ();
      tree def = gimple_phi_arg_def (phi, src_indx);
      location_t locus = gimple_phi_arg_location (phi, src_indx);

      if (TREE_CODE (def) == SSA_NAME
	  && !virtual_operand_p (gimple_phi_result (phi)))
	def = get_value_locus_in_path (def, path, bb, idx, &locus);

      add_phi_arg (phi, def, tgt_e, locus);
    }
}

/* We have recently made a copy of ORIG_BB, including its outgoing
   edges.  The copy is NEW_BB.  Every PHI node in every direct successor of
   ORIG_BB has a new argument associated with edge from NEW_BB to the
   successor.  Initialize the PHI argument so that it is equal to the PHI
   argument associated with the edge from ORIG_BB to the successor.
   PATH and IDX are used to check if the new PHI argument has constant
   value in a flow sensitive manner.  */

static void
update_destination_phis (basic_block orig_bb, basic_block new_bb,
			 vec<jump_thread_edge *> *path, int idx)
{
  edge_iterator ei;
  edge e;

  FOR_EACH_EDGE (e, ei, orig_bb->succs)
    {
      edge e2 = find_edge (new_bb, e->dest);
      copy_phi_args (e->dest, e, e2, path, idx);
    }
}

/* Given a duplicate block and its single destination (both stored
   in RD).  Create an edge between the duplicate and its single
   destination.

   Add an additional argument to any PHI nodes at the single
   destination.  IDX is the start node in jump threading path
   we start to check to see if the new PHI argument has constant
   value along the jump threading path.  */

static void
create_edge_and_update_destination_phis (struct redirection_data *rd,
					 basic_block bb, int idx)
{
  edge e = make_single_succ_edge (bb, rd->path->last ()->e->dest, EDGE_FALLTHRU);

  rescan_loop_exit (e, true, false);

  /* We used to copy the thread path here.  That was added in 2007
     and dutifully updated through the representation changes in 2013.

     In 2013 we added code to thread from an interior node through
     the backedge to another interior node.  That runs after the code
     to thread through loop headers from outside the loop.

     The latter may delete edges in the CFG, including those
     which appeared in the jump threading path we copied here.  Thus
     we'd end up using a dangling pointer.

     After reviewing the 2007/2011 code, I can't see how anything
     depended on copying the AUX field and clearly copying the jump
     threading path is problematical due to embedded edge pointers.
     It has been removed.  */
  e->aux = NULL;

  /* If there are any PHI nodes at the destination of the outgoing edge
     from the duplicate block, then we will need to add a new argument
     to them.  The argument should have the same value as the argument
     associated with the outgoing edge stored in RD.  */
  copy_phi_args (e->dest, rd->path->last ()->e, e, rd->path, idx);
}

/* Look through PATH beginning at START and return TRUE if there are
   any additional blocks that need to be duplicated.  Otherwise,
   return FALSE.  */
static bool
any_remaining_duplicated_blocks (vec<jump_thread_edge *> *path,
				 unsigned int start)
{
  for (unsigned int i = start + 1; i < path->length (); i++)
    {
      if ((*path)[i]->type == EDGE_COPY_SRC_JOINER_BLOCK
	  || (*path)[i]->type == EDGE_COPY_SRC_BLOCK)
	return true;
    }
  return false;
}


/* Compute the amount of profile count coming into the jump threading
   path stored in RD that we are duplicating, returned in PATH_IN_COUNT_PTR and
   PATH_IN_FREQ_PTR, as well as the amount of counts flowing out of the
   duplicated path, returned in PATH_OUT_COUNT_PTR.  LOCAL_INFO is used to
   identify blocks duplicated for jump threading, which have duplicated
   edges that need to be ignored in the analysis.  Return true if path contains
   a joiner, false otherwise.

   In the non-joiner case, this is straightforward - all the counts
   flowing into the jump threading path should flow through the duplicated
   block and out of the duplicated path.

   In the joiner case, it is very tricky.  Some of the counts flowing into
   the original path go offpath at the joiner.  The problem is that while
   we know how much total count goes off-path in the original control flow,
   we don't know how many of the counts corresponding to just the jump
   threading path go offpath at the joiner.

   For example, assume we have the following control flow and identified
   jump threading paths:

		A     B     C
		 \    |    /
	       Ea \   |Eb / Ec
		   \  |  /
		    v v v
		      J       <-- Joiner
		     / \
		Eoff/   \Eon
		   /     \
		  v       v
		Soff     Son  <--- Normal
			 /\
		      Ed/  \ Ee
		       /    \
		      v     v
		      D      E

	    Jump threading paths: A -> J -> Son -> D (path 1)
				  C -> J -> Son -> E (path 2)

   Note that the control flow could be more complicated:
   - Each jump threading path may have more than one incoming edge.  I.e. A and
   Ea could represent multiple incoming blocks/edges that are included in
   path 1.
   - There could be EDGE_NO_COPY_SRC_BLOCK edges after the joiner (either
   before or after the "normal" copy block).  These are not duplicated onto
   the jump threading path, as they are single-successor.
   - Any of the blocks along the path may have other incoming edges that
   are not part of any jump threading path, but add profile counts along
   the path.

   In the above example, after all jump threading is complete, we will
   end up with the following control flow:

		A	   B	       C
		|	   |	       |
	      Ea|	   |Eb	       |Ec
		|	   |	       |
		v	   v	       v
	       Ja	   J	      Jc
	       / \	  / \Eon'     / \
	  Eona/   \   ---/---\--------   \Eonc
	     /     \ /  /     \		  \
	    v       v  v       v	  v
	   Sona     Soff      Son	Sonc
	     \		       /\	  /
	      \___________    /  \  _____/
			  \  /    \/
			   vv      v
			    D      E

   The main issue to notice here is that when we are processing path 1
   (A->J->Son->D) we need to figure out the outgoing edge weights to
   the duplicated edges Ja->Sona and Ja->Soff, while ensuring that the
   sum of the incoming weights to D remain Ed.  The problem with simply
   assuming that Ja (and Jc when processing path 2) has the same outgoing
   probabilities to its successors as the original block J, is that after
   all paths are processed and other edges/counts removed (e.g. none
   of Ec will reach D after processing path 2), we may end up with not
   enough count flowing along duplicated edge Sona->D.

   Therefore, in the case of a joiner, we keep track of all counts
   coming in along the current path, as well as from predecessors not
   on any jump threading path (Eb in the above example).  While we
   first assume that the duplicated Eona for Ja->Sona has the same
   probability as the original, we later compensate for other jump
   threading paths that may eliminate edges.  We do that by keep track
   of all counts coming into the original path that are not in a jump
   thread (Eb in the above example, but as noted earlier, there could
   be other predecessors incoming to the path at various points, such
   as at Son).  Call this cumulative non-path count coming into the path
   before D as Enonpath.  We then ensure that the count from Sona->D is as at
   least as big as (Ed - Enonpath), but no bigger than the minimum
   weight along the jump threading path.  The probabilities of both the
   original and duplicated joiner block J and Ja will be adjusted
   accordingly after the updates.  */

static bool
compute_path_counts (struct redirection_data *rd,
		     ssa_local_info_t *local_info,
		     profile_count *path_in_count_ptr,
		     profile_count *path_out_count_ptr)
{
  edge e = rd->incoming_edges->e;
  vec<jump_thread_edge *> *path = THREAD_PATH (e);
  edge elast = path->last ()->e;
  profile_count nonpath_count = profile_count::zero ();
  bool has_joiner = false;
  profile_count path_in_count = profile_count::zero ();

  /* Start by accumulating incoming edge counts to the path's first bb
     into a couple buckets:
	path_in_count: total count of incoming edges that flow into the
		  current path.
	nonpath_count: total count of incoming edges that are not
		  flowing along *any* path.  These are the counts
		  that will still flow along the original path after
		  all path duplication is done by potentially multiple
		  calls to this routine.
     (any other incoming edge counts are for a different jump threading
     path that will be handled by a later call to this routine.)
     To make this easier, start by recording all incoming edges that flow into
     the current path in a bitmap.  We could add up the path's incoming edge
     counts here, but we still need to walk all the first bb's incoming edges
     below to add up the counts of the other edges not included in this jump
     threading path.  */
  struct el *next, *el;
  auto_bitmap in_edge_srcs;
  for (el = rd->incoming_edges; el; el = next)
    {
      next = el->next;
      bitmap_set_bit (in_edge_srcs, el->e->src->index);
    }
  edge ein;
  edge_iterator ei;
  FOR_EACH_EDGE (ein, ei, e->dest->preds)
    {
      vec<jump_thread_edge *> *ein_path = THREAD_PATH (ein);
      /* Simply check the incoming edge src against the set captured above.  */
      if (ein_path
	  && bitmap_bit_p (in_edge_srcs, (*ein_path)[0]->e->src->index))
	{
	  /* It is necessary but not sufficient that the last path edges
	     are identical.  There may be different paths that share the
	     same last path edge in the case where the last edge has a nocopy
	     source block.  */
	  gcc_assert (ein_path->last ()->e == elast);
	  path_in_count += ein->count ();
	}
      else if (!ein_path)
	{
	  /* Keep track of the incoming edges that are not on any jump-threading
	     path.  These counts will still flow out of original path after all
	     jump threading is complete.  */
	    nonpath_count += ein->count ();
	}
    }

  /* Now compute the fraction of the total count coming into the first
     path bb that is from the current threading path.  */
  profile_count total_count = e->dest->count;
  /* Handle incoming profile insanities.  */
  if (total_count < path_in_count)
    path_in_count = total_count;
  profile_probability onpath_scale = path_in_count.probability_in (total_count);

  /* Walk the entire path to do some more computation in order to estimate
     how much of the path_in_count will flow out of the duplicated threading
     path.  In the non-joiner case this is straightforward (it should be
     the same as path_in_count, although we will handle incoming profile
     insanities by setting it equal to the minimum count along the path).

     In the joiner case, we need to estimate how much of the path_in_count
     will stay on the threading path after the joiner's conditional branch.
     We don't really know for sure how much of the counts
     associated with this path go to each successor of the joiner, but we'll
     estimate based on the fraction of the total count coming into the path
     bb was from the threading paths (computed above in onpath_scale).
     Afterwards, we will need to do some fixup to account for other threading
     paths and possible profile insanities.

     In order to estimate the joiner case's counts we also need to update
     nonpath_count with any additional counts coming into the path.  Other
     blocks along the path may have additional predecessors from outside
     the path.  */
  profile_count path_out_count = path_in_count;
  profile_count min_path_count = path_in_count;
  for (unsigned int i = 1; i < path->length (); i++)
    {
      edge epath = (*path)[i]->e;
      profile_count cur_count = epath->count ();
      if ((*path)[i]->type == EDGE_COPY_SRC_JOINER_BLOCK)
	{
	  has_joiner = true;
	  cur_count = cur_count.apply_probability (onpath_scale);
	}
      /* In the joiner case we need to update nonpath_count for any edges
	 coming into the path that will contribute to the count flowing
	 into the path successor.  */
      if (has_joiner && epath != elast)
	{
	  /* Look for other incoming edges after joiner.  */
	  FOR_EACH_EDGE (ein, ei, epath->dest->preds)
	    {
	      if (ein != epath
		  /* Ignore in edges from blocks we have duplicated for a
		     threading path, which have duplicated edge counts until
		     they are redirected by an invocation of this routine.  */
		  && !bitmap_bit_p (local_info->duplicate_blocks,
				    ein->src->index))
		nonpath_count += ein->count ();
	    }
	}
      if (cur_count < path_out_count)
	path_out_count = cur_count;
      if (epath->count () < min_path_count)
	min_path_count = epath->count ();
    }

  /* We computed path_out_count above assuming that this path targeted
     the joiner's on-path successor with the same likelihood as it
     reached the joiner.  However, other thread paths through the joiner
     may take a different path through the normal copy source block
     (i.e. they have a different elast), meaning that they do not
     contribute any counts to this path's elast.  As a result, it may
     turn out that this path must have more count flowing to the on-path
     successor of the joiner.  Essentially, all of this path's elast
     count must be contributed by this path and any nonpath counts
     (since any path through the joiner with a different elast will not
     include a copy of this elast in its duplicated path).
     So ensure that this path's path_out_count is at least the
     difference between elast->count () and nonpath_count.  Otherwise the edge
     counts after threading will not be sane.  */
  if (local_info->need_profile_correction
      && has_joiner && path_out_count < elast->count () - nonpath_count)
    {
      path_out_count = elast->count () - nonpath_count;
      /* But neither can we go above the minimum count along the path
	 we are duplicating.  This can be an issue due to profile
	 insanities coming in to this pass.  */
      if (path_out_count > min_path_count)
	path_out_count = min_path_count;
    }

  *path_in_count_ptr = path_in_count;
  *path_out_count_ptr = path_out_count;
  return has_joiner;
}


/* Update the counts and frequencies for both an original path
   edge EPATH and its duplicate EDUP.  The duplicate source block
   will get a count of PATH_IN_COUNT and PATH_IN_FREQ,
   and the duplicate edge EDUP will have a count of PATH_OUT_COUNT.  */
static void
update_profile (edge epath, edge edup, profile_count path_in_count,
		profile_count path_out_count)
{

  /* First update the duplicated block's count.  */
  if (edup)
    {
      basic_block dup_block = edup->src;

      /* Edup's count is reduced by path_out_count.  We need to redistribute
         probabilities to the remaining edges.  */

      edge esucc;
      edge_iterator ei;
      profile_probability edup_prob
	 = path_out_count.probability_in (path_in_count);

      /* Either scale up or down the remaining edges.
	 probabilities are always in range <0,1> and thus we can't do
	 both by same loop.  */
      if (edup->probability > edup_prob)
	{
	   profile_probability rev_scale
	     = (profile_probability::always () - edup->probability)
	       / (profile_probability::always () - edup_prob);
	   FOR_EACH_EDGE (esucc, ei, dup_block->succs)
	     if (esucc != edup)
	       esucc->probability /= rev_scale;
	}
      else if (edup->probability < edup_prob)
	{
	   profile_probability scale
	     = (profile_probability::always () - edup_prob)
	       / (profile_probability::always () - edup->probability);
	  FOR_EACH_EDGE (esucc, ei, dup_block->succs)
	    if (esucc != edup)
	      esucc->probability *= scale;
	}
      if (edup_prob.initialized_p ())
        edup->probability = edup_prob;

      gcc_assert (!dup_block->count.initialized_p ());
      dup_block->count = path_in_count;
    }

  if (path_in_count == profile_count::zero ())
    return;

  profile_count final_count = epath->count () - path_out_count;

  /* Now update the original block's count in the
     opposite manner - remove the counts/freq that will flow
     into the duplicated block.  Handle underflow due to precision/
     rounding issues.  */
  epath->src->count -= path_in_count;

  /* Next update this path edge's original and duplicated counts.  We know
     that the duplicated path will have path_out_count flowing
     out of it (in the joiner case this is the count along the duplicated path
     out of the duplicated joiner).  This count can then be removed from the
     original path edge.  */

  edge esucc;
  edge_iterator ei;
  profile_probability epath_prob = final_count.probability_in (epath->src->count);

  if (epath->probability > epath_prob)
    {
       profile_probability rev_scale
	 = (profile_probability::always () - epath->probability)
	   / (profile_probability::always () - epath_prob);
       FOR_EACH_EDGE (esucc, ei, epath->src->succs)
	 if (esucc != epath)
	   esucc->probability /= rev_scale;
    }
  else if (epath->probability < epath_prob)
    {
       profile_probability scale
	 = (profile_probability::always () - epath_prob)
	   / (profile_probability::always () - epath->probability);
      FOR_EACH_EDGE (esucc, ei, epath->src->succs)
	if (esucc != epath)
	  esucc->probability *= scale;
    }
  if (epath_prob.initialized_p ())
    epath->probability = epath_prob;
}

/* Wire up the outgoing edges from the duplicate blocks and
   update any PHIs as needed.  Also update the profile counts
   on the original and duplicate blocks and edges.  */
void
ssa_fix_duplicate_block_edges (struct redirection_data *rd,
			       ssa_local_info_t *local_info)
{
  bool multi_incomings = (rd->incoming_edges->next != NULL);
  edge e = rd->incoming_edges->e;
  vec<jump_thread_edge *> *path = THREAD_PATH (e);
  edge elast = path->last ()->e;
  profile_count path_in_count = profile_count::zero ();
  profile_count path_out_count = profile_count::zero ();

  /* First determine how much profile count to move from original
     path to the duplicate path.  This is tricky in the presence of
     a joiner (see comments for compute_path_counts), where some portion
     of the path's counts will flow off-path from the joiner.  In the
     non-joiner case the path_in_count and path_out_count should be the
     same.  */
  bool has_joiner = compute_path_counts (rd, local_info,
					 &path_in_count, &path_out_count);

  for (unsigned int count = 0, i = 1; i < path->length (); i++)
    {
      edge epath = (*path)[i]->e;

      /* If we were threading through an joiner block, then we want
	 to keep its control statement and redirect an outgoing edge.
	 Else we want to remove the control statement & edges, then create
	 a new outgoing edge.  In both cases we may need to update PHIs.  */
      if ((*path)[i]->type == EDGE_COPY_SRC_JOINER_BLOCK)
	{
	  edge victim;
	  edge e2;

	  gcc_assert (has_joiner);

	  /* This updates the PHIs at the destination of the duplicate
	     block.  Pass 0 instead of i if we are threading a path which
	     has multiple incoming edges.  */
	  update_destination_phis (local_info->bb, rd->dup_blocks[count],
				   path, multi_incomings ? 0 : i);

	  /* Find the edge from the duplicate block to the block we're
	     threading through.  That's the edge we want to redirect.  */
	  victim = find_edge (rd->dup_blocks[count], (*path)[i]->e->dest);

	  /* If there are no remaining blocks on the path to duplicate,
	     then redirect VICTIM to the final destination of the jump
	     threading path.  */
	  if (!any_remaining_duplicated_blocks (path, i))
	    {
	      e2 = redirect_edge_and_branch (victim, elast->dest);
	      /* If we redirected the edge, then we need to copy PHI arguments
		 at the target.  If the edge already existed (e2 != victim
		 case), then the PHIs in the target already have the correct
		 arguments.  */
	      if (e2 == victim)
		copy_phi_args (e2->dest, elast, e2,
			       path, multi_incomings ? 0 : i);
	    }
	  else
	    {
	      /* Redirect VICTIM to the next duplicated block in the path.  */
	      e2 = redirect_edge_and_branch (victim, rd->dup_blocks[count + 1]);

	      /* We need to update the PHIs in the next duplicated block.  We
		 want the new PHI args to have the same value as they had
		 in the source of the next duplicate block.

		 Thus, we need to know which edge we traversed into the
		 source of the duplicate.  Furthermore, we may have
		 traversed many edges to reach the source of the duplicate.

		 Walk through the path starting at element I until we
		 hit an edge marked with EDGE_COPY_SRC_BLOCK.  We want
		 the edge from the prior element.  */
	      for (unsigned int j = i + 1; j < path->length (); j++)
		{
		  if ((*path)[j]->type == EDGE_COPY_SRC_BLOCK)
		    {
		      copy_phi_arg_into_existing_phi ((*path)[j - 1]->e, e2);
		      break;
		    }
		}
	    }

	  /* Update the counts of both the original block
	     and path edge, and the duplicates.  The path duplicate's
	     incoming count are the totals for all edges
	     incoming to this jump threading path computed earlier.
	     And we know that the duplicated path will have path_out_count
	     flowing out of it (i.e. along the duplicated path out of the
	     duplicated joiner).  */
	  update_profile (epath, e2, path_in_count, path_out_count);
	}
      else if ((*path)[i]->type == EDGE_COPY_SRC_BLOCK)
	{
	  remove_ctrl_stmt_and_useless_edges (rd->dup_blocks[count], NULL);
	  create_edge_and_update_destination_phis (rd, rd->dup_blocks[count],
						   multi_incomings ? 0 : i);
	  if (count == 1)
	    single_succ_edge (rd->dup_blocks[1])->aux = NULL;

	  /* Update the counts of both the original block
	     and path edge, and the duplicates.  Since we are now after
	     any joiner that may have existed on the path, the count
	     flowing along the duplicated threaded path is path_out_count.
	     If we didn't have a joiner, then cur_path_freq was the sum
	     of the total frequencies along all incoming edges to the
	     thread path (path_in_freq).  If we had a joiner, it would have
	     been updated at the end of that handling to the edge frequency
	     along the duplicated joiner path edge.  */
	  update_profile (epath, EDGE_SUCC (rd->dup_blocks[count], 0),
			  path_out_count, path_out_count);
	}
      else
	{
	  /* No copy case.  In this case we don't have an equivalent block
	     on the duplicated thread path to update, but we do need
	     to remove the portion of the counts/freqs that were moved
	     to the duplicated path from the counts/freqs flowing through
	     this block on the original path.  Since all the no-copy edges
	     are after any joiner, the removed count is the same as
	     path_out_count.

	     If we didn't have a joiner, then cur_path_freq was the sum
	     of the total frequencies along all incoming edges to the
	     thread path (path_in_freq).  If we had a joiner, it would have
	     been updated at the end of that handling to the edge frequency
	     along the duplicated joiner path edge.  */
	   update_profile (epath, NULL, path_out_count, path_out_count);
	}

      /* Increment the index into the duplicated path when we processed
	 a duplicated block.  */
      if ((*path)[i]->type == EDGE_COPY_SRC_JOINER_BLOCK
	  || (*path)[i]->type == EDGE_COPY_SRC_BLOCK)
	{
	  count++;
	}
    }
}

/* Hash table traversal callback routine to create duplicate blocks.  */

int
ssa_create_duplicates (struct redirection_data **slot,
		       ssa_local_info_t *local_info)
{
  struct redirection_data *rd = *slot;

  /* The second duplicated block in a jump threading path is specific
     to the path.  So it gets stored in RD rather than in LOCAL_DATA.

     Each time we're called, we have to look through the path and see
     if a second block needs to be duplicated.

     Note the search starts with the third edge on the path.  The first
     edge is the incoming edge, the second edge always has its source
     duplicated.  Thus we start our search with the third edge.  */
  vec<jump_thread_edge *> *path = rd->path;
  for (unsigned int i = 2; i < path->length (); i++)
    {
      if ((*path)[i]->type == EDGE_COPY_SRC_BLOCK
	  || (*path)[i]->type == EDGE_COPY_SRC_JOINER_BLOCK)
	{
	  create_block_for_threading ((*path)[i]->e->src, rd, 1,
				      &local_info->duplicate_blocks);
	  break;
	}
    }

  /* Create a template block if we have not done so already.  Otherwise
     use the template to create a new block.  */
  if (local_info->template_block == NULL)
    {
      create_block_for_threading ((*path)[1]->e->src, rd, 0,
				  &local_info->duplicate_blocks);
      local_info->template_block = rd->dup_blocks[0];
      local_info->template_last_to_copy
	= gsi_last_bb (local_info->template_block);

      /* We do not create any outgoing edges for the template.  We will
	 take care of that in a later traversal.  That way we do not
	 create edges that are going to just be deleted.  */
    }
  else
    {
      gimple_seq seq = NULL;
      if (gsi_stmt (local_info->template_last_to_copy)
	  != gsi_stmt (gsi_last_bb (local_info->template_block)))
	{
	  if (gsi_end_p (local_info->template_last_to_copy))
	    {
	      seq = bb_seq (local_info->template_block);
	      set_bb_seq (local_info->template_block, NULL);
	    }
	  else
	    seq = gsi_split_seq_after (local_info->template_last_to_copy);
	}
      create_block_for_threading (local_info->template_block, rd, 0,
				  &local_info->duplicate_blocks);
      if (seq)
	{
	  if (gsi_end_p (local_info->template_last_to_copy))
	    set_bb_seq (local_info->template_block, seq);
	  else
	    gsi_insert_seq_after (&local_info->template_last_to_copy,
				  seq, GSI_SAME_STMT);
	}

      /* Go ahead and wire up outgoing edges and update PHIs for the duplicate
	 block.   */
      ssa_fix_duplicate_block_edges (rd, local_info);
    }

  if (MAY_HAVE_DEBUG_STMTS)
    {
      /* Copy debug stmts from each NO_COPY src block to the block
	 that would have been its predecessor, if we can append to it
	 (we can't add stmts after a block-ending stmt), or prepending
	 to the duplicate of the successor, if there is one.  If
	 there's no duplicate successor, we'll mostly drop the blocks
	 on the floor; propagate_threaded_block_debug_into, called
	 elsewhere, will consolidate and preserve the effects of the
	 binds, but none of the markers.  */
      gimple_stmt_iterator copy_to = gsi_last_bb (rd->dup_blocks[0]);
      if (!gsi_end_p (copy_to))
	{
	  if (stmt_ends_bb_p (gsi_stmt (copy_to)))
	    {
	      if (rd->dup_blocks[1])
		copy_to = gsi_after_labels (rd->dup_blocks[1]);
	      else
		copy_to = gsi_none ();
	    }
	  else
	    gsi_next (&copy_to);
	}
      for (unsigned int i = 2, j = 0; i < path->length (); i++)
	if ((*path)[i]->type == EDGE_NO_COPY_SRC_BLOCK
	    && gsi_bb (copy_to))
	  {
	    for (gimple_stmt_iterator gsi = gsi_start_bb ((*path)[i]->e->src);
		 !gsi_end_p (gsi); gsi_next (&gsi))
	      {
		if (!is_gimple_debug (gsi_stmt (gsi)))
		  continue;
		gimple *stmt = gsi_stmt (gsi);
		gimple *copy = gimple_copy (stmt);
		gsi_insert_before (&copy_to, copy, GSI_SAME_STMT);
	      }
	  }
	else if ((*path)[i]->type == EDGE_COPY_SRC_BLOCK
		 || (*path)[i]->type == EDGE_COPY_SRC_JOINER_BLOCK)
	  {
	    j++;
	    gcc_assert (j < 2);
	    copy_to = gsi_last_bb (rd->dup_blocks[j]);
	    if (!gsi_end_p (copy_to))
	      {
		if (stmt_ends_bb_p (gsi_stmt (copy_to)))
		  copy_to = gsi_none ();
		else
		  gsi_next (&copy_to);
	      }
	  }
    }

  /* Keep walking the hash table.  */
  return 1;
}

/* We did not create any outgoing edges for the template block during
   block creation.  This hash table traversal callback creates the
   outgoing edge for the template block.  */

inline int
ssa_fixup_template_block (struct redirection_data **slot,
			  ssa_local_info_t *local_info)
{
  struct redirection_data *rd = *slot;

  /* If this is the template block halt the traversal after updating
     it appropriately.

     If we were threading through an joiner block, then we want
     to keep its control statement and redirect an outgoing edge.
     Else we want to remove the control statement & edges, then create
     a new outgoing edge.  In both cases we may need to update PHIs.  */
  if (rd->dup_blocks[0] && rd->dup_blocks[0] == local_info->template_block)
    {
      ssa_fix_duplicate_block_edges (rd, local_info);
      return 0;
    }

  return 1;
}

/* Hash table traversal callback to redirect each incoming edge
   associated with this hash table element to its new destination.  */

static int
ssa_redirect_edges (struct redirection_data **slot,
		    ssa_local_info_t *local_info)
{
  struct redirection_data *rd = *slot;
  struct el *next, *el;

  /* Walk over all the incoming edges associated with this hash table
     entry.  */
  for (el = rd->incoming_edges; el; el = next)
    {
      edge e = el->e;
      vec<jump_thread_edge *> *path = THREAD_PATH (e);

      /* Go ahead and free this element from the list.  Doing this now
	 avoids the need for another list walk when we destroy the hash
	 table.  */
      next = el->next;
      free (el);

      local_info->num_threaded_edges++;

      if (rd->dup_blocks[0])
	{
	  edge e2;

	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file, "  Threaded jump %d --> %d to %d\n",
		     e->src->index, e->dest->index, rd->dup_blocks[0]->index);

	  /* Redirect the incoming edge (possibly to the joiner block) to the
	     appropriate duplicate block.  */
	  e2 = redirect_edge_and_branch (e, rd->dup_blocks[0]);
	  gcc_assert (e == e2);
	  flush_pending_stmts (e2);
	}

      /* Go ahead and clear E->aux.  It's not needed anymore and failure
	 to clear it will cause all kinds of unpleasant problems later.  */
      path->release ();
      e->aux = NULL;

    }

  /* Indicate that we actually threaded one or more jumps.  */
  if (rd->incoming_edges)
    local_info->jumps_threaded = true;

  return 1;
}

/* Return true if this block has no executable statements other than
   a simple ctrl flow instruction.  When the number of outgoing edges
   is one, this is equivalent to a "forwarder" block.  */

static bool
redirection_block_p (basic_block bb)
{
  gimple_stmt_iterator gsi;

  /* Advance to the first executable statement.  */
  gsi = gsi_start_bb (bb);
  while (!gsi_end_p (gsi)
	 && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
	     || is_gimple_debug (gsi_stmt (gsi))
	     || gimple_nop_p (gsi_stmt (gsi))
	     || gimple_clobber_p (gsi_stmt (gsi))))
    gsi_next (&gsi);

  /* Check if this is an empty block.  */
  if (gsi_end_p (gsi))
    return true;

  /* Test that we've reached the terminating control statement.  */
  return gsi_stmt (gsi)
	 && (gimple_code (gsi_stmt (gsi)) == GIMPLE_COND
	     || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
	     || gimple_code (gsi_stmt (gsi)) == GIMPLE_SWITCH);
}

/* BB is a block which ends with a COND_EXPR or SWITCH_EXPR and when BB
   is reached via one or more specific incoming edges, we know which
   outgoing edge from BB will be traversed.

   We want to redirect those incoming edges to the target of the
   appropriate outgoing edge.  Doing so avoids a conditional branch
   and may expose new optimization opportunities.  Note that we have
   to update dominator tree and SSA graph after such changes.

   The key to keeping the SSA graph update manageable is to duplicate
   the side effects occurring in BB so that those side effects still
   occur on the paths which bypass BB after redirecting edges.

   We accomplish this by creating duplicates of BB and arranging for
   the duplicates to unconditionally pass control to one specific
   successor of BB.  We then revector the incoming edges into BB to
   the appropriate duplicate of BB.

   If NOLOOP_ONLY is true, we only perform the threading as long as it
   does not affect the structure of the loops in a nontrivial way.

   If JOINERS is true, then thread through joiner blocks as well.  */

bool
jump_thread_path_registry::thread_block_1 (basic_block bb,
					   bool noloop_only,
					   bool joiners)
{
  /* E is an incoming edge into BB that we may or may not want to
     redirect to a duplicate of BB.  */
  edge e, e2;
  edge_iterator ei;
  ssa_local_info_t local_info;

  local_info.duplicate_blocks = BITMAP_ALLOC (NULL);
  local_info.need_profile_correction = false;
  local_info.num_threaded_edges = 0;

  /* To avoid scanning a linear array for the element we need we instead
     use a hash table.  For normal code there should be no noticeable
     difference.  However, if we have a block with a large number of
     incoming and outgoing edges such linear searches can get expensive.  */
  m_redirection_data
    = new hash_table<struct redirection_data> (EDGE_COUNT (bb->succs));

  /* Record each unique threaded destination into a hash table for
     efficient lookups.  */
  edge last = NULL;
  FOR_EACH_EDGE (e, ei, bb->preds)
    {
      if (e->aux == NULL)
	continue;

      vec<jump_thread_edge *> *path = THREAD_PATH (e);

      if (((*path)[1]->type == EDGE_COPY_SRC_JOINER_BLOCK && !joiners)
	  || ((*path)[1]->type == EDGE_COPY_SRC_BLOCK && joiners))
	continue;

      e2 = path->last ()->e;
      if (!e2 || noloop_only)
	{
	  /* If NOLOOP_ONLY is true, we only allow threading through the
	     header of a loop to exit edges.  */

	  /* One case occurs when there was loop header buried in a jump
	     threading path that crosses loop boundaries.  We do not try
	     and thread this elsewhere, so just cancel the jump threading
	     request by clearing the AUX field now.  */
	  if (bb->loop_father != e2->src->loop_father
	      && (!loop_exit_edge_p (e2->src->loop_father, e2)
		  || flow_loop_nested_p (bb->loop_father,
					 e2->dest->loop_father)))
	    {
	      /* Since this case is not handled by our special code
		 to thread through a loop header, we must explicitly
		 cancel the threading request here.  */
	      path->release ();
	      e->aux = NULL;
	      continue;
	    }

	  /* Another case occurs when trying to thread through our
	     own loop header, possibly from inside the loop.  We will
	     thread these later.  */
	  unsigned int i;
	  for (i = 1; i < path->length (); i++)
	    {
	      if ((*path)[i]->e->src == bb->loop_father->header
		  && (!loop_exit_edge_p (bb->loop_father, e2)
		      || (*path)[1]->type == EDGE_COPY_SRC_JOINER_BLOCK))
		break;
	    }

	  if (i != path->length ())
	    continue;

	  /* Loop parallelization can be confused by the result of
	     threading through the loop exit test back into the loop.
	     However, theading those jumps seems to help other codes.

	     I have been unable to find anything related to the shape of
	     the CFG, the contents of the affected blocks, etc which would
	     allow a more sensible test than what we're using below which
	     merely avoids the optimization when parallelizing loops.  */
	  if (flag_tree_parallelize_loops > 1)
	    {
	      for (i = 1; i < path->length (); i++)
	        if (bb->loop_father == e2->src->loop_father
		    && loop_exits_from_bb_p (bb->loop_father,
					     (*path)[i]->e->src)
		    && !loop_exit_edge_p (bb->loop_father, e2))
		  break;

	      if (i != path->length ())
		{
		  path->release ();
		  e->aux = NULL;
		  continue;
		}
	    }
	}

      /* Insert the outgoing edge into the hash table if it is not
	 already in the hash table.  */
      lookup_redirection_data (e, INSERT);

      /* When we have thread paths through a common joiner with different
	 final destinations, then we may need corrections to deal with
	 profile insanities.  See the big comment before compute_path_counts.  */
      if ((*path)[1]->type == EDGE_COPY_SRC_JOINER_BLOCK)
	{
	  if (!last)
	    last = e2;
	  else if (e2 != last)
	    local_info.need_profile_correction = true;
	}
    }

  /* We do not update dominance info.  */
  free_dominance_info (CDI_DOMINATORS);

  /* We know we only thread through the loop header to loop exits.
     Let the basic block duplication hook know we are not creating
     a multiple entry loop.  */
  if (noloop_only
      && bb == bb->loop_father->header)
    set_loop_copy (bb->loop_father, loop_outer (bb->loop_father));

  /* Now create duplicates of BB.

     Note that for a block with a high outgoing degree we can waste
     a lot of time and memory creating and destroying useless edges.

     So we first duplicate BB and remove the control structure at the
     tail of the duplicate as well as all outgoing edges from the
     duplicate.  We then use that duplicate block as a template for
     the rest of the duplicates.  */
  local_info.template_block = NULL;
  local_info.bb = bb;
  local_info.jumps_threaded = false;
  m_redirection_data->traverse <ssa_local_info_t *, ssa_create_duplicates>
			    (&local_info);

  /* The template does not have an outgoing edge.  Create that outgoing
     edge and update PHI nodes as the edge's target as necessary.

     We do this after creating all the duplicates to avoid creating
     unnecessary edges.  */
  m_redirection_data->traverse <ssa_local_info_t *, ssa_fixup_template_block>
			    (&local_info);

  /* The hash table traversals above created the duplicate blocks (and the
     statements within the duplicate blocks).  This loop creates PHI nodes for
     the duplicated blocks and redirects the incoming edges into BB to reach
     the duplicates of BB.  */
  m_redirection_data->traverse <ssa_local_info_t *, ssa_redirect_edges>
			    (&local_info);

  /* Done with this block.  Clear REDIRECTION_DATA.  */
  delete m_redirection_data;
  m_redirection_data = NULL;

  if (noloop_only
      && bb == bb->loop_father->header)
    set_loop_copy (bb->loop_father, NULL);

  BITMAP_FREE (local_info.duplicate_blocks);
  local_info.duplicate_blocks = NULL;

  m_num_threaded_edges += local_info.num_threaded_edges;

  /* Indicate to our caller whether or not any jumps were threaded.  */
  return local_info.jumps_threaded;
}

/* Wrapper for thread_block_1 so that we can first handle jump
   thread paths which do not involve copying joiner blocks, then
   handle jump thread paths which have joiner blocks.

   By doing things this way we can be as aggressive as possible and
   not worry that copying a joiner block will create a jump threading
   opportunity.  */

bool
jump_thread_path_registry::thread_block (basic_block bb, bool noloop_only)
{
  bool retval;
  retval = thread_block_1 (bb, noloop_only, false);
  retval |= thread_block_1 (bb, noloop_only, true);
  return retval;
}

/* Callback for dfs_enumerate_from.  Returns true if BB is different
   from STOP and DBDS_CE_STOP.  */

static basic_block dbds_ce_stop;
static bool
dbds_continue_enumeration_p (const_basic_block bb, const void *stop)
{
  return (bb != (const_basic_block) stop
	  && bb != dbds_ce_stop);
}

/* Evaluates the dominance relationship of latch of the LOOP and BB, and
   returns the state.  */

enum bb_dom_status
determine_bb_domination_status (class loop *loop, basic_block bb)
{
  basic_block *bblocks;
  unsigned nblocks, i;
  bool bb_reachable = false;
  edge_iterator ei;
  edge e;

  /* This function assumes BB is a successor of LOOP->header.
     If that is not the case return DOMST_NONDOMINATING which
     is always safe.  */
    {
      bool ok = false;

      FOR_EACH_EDGE (e, ei, bb->preds)
	{
     	  if (e->src == loop->header)
	    {
	      ok = true;
	      break;
	    }
	}

      if (!ok)
	return DOMST_NONDOMINATING;
    }

  if (bb == loop->latch)
    return DOMST_DOMINATING;

  /* Check that BB dominates LOOP->latch, and that it is back-reachable
     from it.  */

  bblocks = XCNEWVEC (basic_block, loop->num_nodes);
  dbds_ce_stop = loop->header;
  nblocks = dfs_enumerate_from (loop->latch, 1, dbds_continue_enumeration_p,
				bblocks, loop->num_nodes, bb);
  for (i = 0; i < nblocks; i++)
    FOR_EACH_EDGE (e, ei, bblocks[i]->preds)
      {
	if (e->src == loop->header)
	  {
	    free (bblocks);
	    return DOMST_NONDOMINATING;
	  }
	if (e->src == bb)
	  bb_reachable = true;
      }

  free (bblocks);
  return (bb_reachable ? DOMST_DOMINATING : DOMST_LOOP_BROKEN);
}

/* Thread jumps through the header of LOOP.  Returns true if cfg changes.
   If MAY_PEEL_LOOP_HEADERS is false, we avoid threading from entry edges
   to the inside of the loop.  */

bool
jump_thread_path_registry::thread_through_loop_header
				(class loop *loop,
				 bool may_peel_loop_headers)
{
  basic_block header = loop->header;
  edge e, tgt_edge, latch = loop_latch_edge (loop);
  edge_iterator ei;
  basic_block tgt_bb, atgt_bb;
  enum bb_dom_status domst;

  /* We have already threaded through headers to exits, so all the threading
     requests now are to the inside of the loop.  We need to avoid creating
     irreducible regions (i.e., loops with more than one entry block), and
     also loop with several latch edges, or new subloops of the loop (although
     there are cases where it might be appropriate, it is difficult to decide,
     and doing it wrongly may confuse other optimizers).

     We could handle more general cases here.  However, the intention is to
     preserve some information about the loop, which is impossible if its
     structure changes significantly, in a way that is not well understood.
     Thus we only handle few important special cases, in which also updating
     of the loop-carried information should be feasible:

     1) Propagation of latch edge to a block that dominates the latch block
	of a loop.  This aims to handle the following idiom:

	first = 1;
	while (1)
	  {
	    if (first)
	      initialize;
	    first = 0;
	    body;
	  }

	After threading the latch edge, this becomes

	first = 1;
	if (first)
	  initialize;
	while (1)
	  {
	    first = 0;
	    body;
	  }

	The original header of the loop is moved out of it, and we may thread
	the remaining edges through it without further constraints.

     2) All entry edges are propagated to a single basic block that dominates
	the latch block of the loop.  This aims to handle the following idiom
	(normally created for "for" loops):

	i = 0;
	while (1)
	  {
	    if (i >= 100)
	      break;
	    body;
	    i++;
	  }

	This becomes

	i = 0;
	while (1)
	  {
	    body;
	    i++;
	    if (i >= 100)
	      break;
	  }
     */

  /* Threading through the header won't improve the code if the header has just
     one successor.  */
  if (single_succ_p (header))
    goto fail;

  if (!may_peel_loop_headers && !redirection_block_p (loop->header))
    goto fail;
  else
    {
      tgt_bb = NULL;
      tgt_edge = NULL;
      FOR_EACH_EDGE (e, ei, header->preds)
	{
	  if (!e->aux)
	    {
	      if (e == latch)
		continue;

	      /* If latch is not threaded, and there is a header
		 edge that is not threaded, we would create loop
		 with multiple entries.  */
	      goto fail;
	    }

	  vec<jump_thread_edge *> *path = THREAD_PATH (e);

	  if ((*path)[1]->type == EDGE_COPY_SRC_JOINER_BLOCK)
	    goto fail;
	  tgt_edge = (*path)[1]->e;
	  atgt_bb = tgt_edge->dest;
	  if (!tgt_bb)
	    tgt_bb = atgt_bb;
	  /* Two targets of threading would make us create loop
	     with multiple entries.  */
	  else if (tgt_bb != atgt_bb)
	    goto fail;
	}

      if (!tgt_bb)
	{
	  /* There are no threading requests.  */
	  return false;
	}

      /* Redirecting to empty loop latch is useless.  */
      if (tgt_bb == loop->latch
	  && empty_block_p (loop->latch))
	goto fail;
    }

  /* The target block must dominate the loop latch, otherwise we would be
     creating a subloop.  */
  domst = determine_bb_domination_status (loop, tgt_bb);
  if (domst == DOMST_NONDOMINATING)
    goto fail;
  if (domst == DOMST_LOOP_BROKEN)
    {
      /* If the loop ceased to exist, mark it as such, and thread through its
	 original header.  */
      mark_loop_for_removal (loop);
      return thread_block (header, false);
    }

  if (tgt_bb->loop_father->header == tgt_bb)
    {
      /* If the target of the threading is a header of a subloop, we need
	 to create a preheader for it, so that the headers of the two loops
	 do not merge.  */
      if (EDGE_COUNT (tgt_bb->preds) > 2)
	{
	  tgt_bb = create_preheader (tgt_bb->loop_father, 0);
	  gcc_assert (tgt_bb != NULL);
	}
      else
	tgt_bb = split_edge (tgt_edge);
    }

  basic_block new_preheader;

  /* Now consider the case entry edges are redirected to the new entry
     block.  Remember one entry edge, so that we can find the new
     preheader (its destination after threading).  */
  FOR_EACH_EDGE (e, ei, header->preds)
    {
      if (e->aux)
	break;
    }

  /* The duplicate of the header is the new preheader of the loop.  Ensure
     that it is placed correctly in the loop hierarchy.  */
  set_loop_copy (loop, loop_outer (loop));

  thread_block (header, false);
  set_loop_copy (loop, NULL);
  new_preheader = e->dest;

  /* Create the new latch block.  This is always necessary, as the latch
     must have only a single successor, but the original header had at
     least two successors.  */
  loop->latch = NULL;
  mfb_kj_edge = single_succ_edge (new_preheader);
  loop->header = mfb_kj_edge->dest;
  latch = make_forwarder_block (tgt_bb, mfb_keep_just, NULL);
  loop->header = latch->dest;
  loop->latch = latch->src;
  return true;

fail:
  /* We failed to thread anything.  Cancel the requests.  */
  FOR_EACH_EDGE (e, ei, header->preds)
    {
      vec<jump_thread_edge *> *path = THREAD_PATH (e);

      if (path)
	{
	  path->release ();
	  e->aux = NULL;
	}
    }
  return false;
}

/* E1 and E2 are edges into the same basic block.  Return TRUE if the
   PHI arguments associated with those edges are equal or there are no
   PHI arguments, otherwise return FALSE.  */

static bool
phi_args_equal_on_edges (edge e1, edge e2)
{
  gphi_iterator gsi;
  int indx1 = e1->dest_idx;
  int indx2 = e2->dest_idx;

  for (gsi = gsi_start_phis (e1->dest); !gsi_end_p (gsi); gsi_next (&gsi))
    {
      gphi *phi = gsi.phi ();

      if (!operand_equal_p (gimple_phi_arg_def (phi, indx1),
			    gimple_phi_arg_def (phi, indx2), 0))
	return false;
    }
  return true;
}

/* Return the number of non-debug statements and non-virtual PHIs in a
   block.  */

static unsigned int
count_stmts_and_phis_in_block (basic_block bb)
{
  unsigned int num_stmts = 0;

  gphi_iterator gpi;
  for (gpi = gsi_start_phis (bb); !gsi_end_p (gpi); gsi_next (&gpi))
    if (!virtual_operand_p (PHI_RESULT (gpi.phi ())))
      num_stmts++;

  gimple_stmt_iterator gsi;
  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    {
      gimple *stmt = gsi_stmt (gsi);
      if (!is_gimple_debug (stmt))
        num_stmts++;
    }

  return num_stmts;
}


/* Walk through the registered jump threads and convert them into a
   form convenient for this pass.

   Any block which has incoming edges threaded to outgoing edges
   will have its entry in THREADED_BLOCK set.

   Any threaded edge will have its new outgoing edge stored in the
   original edge's AUX field.

   This form avoids the need to walk all the edges in the CFG to
   discover blocks which need processing and avoids unnecessary
   hash table lookups to map from threaded edge to new target.  */

void
jump_thread_path_registry::mark_threaded_blocks (bitmap threaded_blocks)
{
  unsigned int i;
  bitmap_iterator bi;
  auto_bitmap tmp;
  basic_block bb;
  edge e;
  edge_iterator ei;

  /* It is possible to have jump threads in which one is a subpath
     of the other.  ie, (A, B), (B, C), (C, D) where B is a joiner
     block and (B, C), (C, D) where no joiner block exists.

     When this occurs ignore the jump thread request with the joiner
     block.  It's totally subsumed by the simpler jump thread request.

     This results in less block copying, simpler CFGs.  More importantly,
     when we duplicate the joiner block, B, in this case we will create
     a new threading opportunity that we wouldn't be able to optimize
     until the next jump threading iteration.

     So first convert the jump thread requests which do not require a
     joiner block.  */
  for (i = 0; i < m_paths.length (); i++)
    {
      vec<jump_thread_edge *> *path = m_paths[i];

      if (path->length () > 1
	  && (*path)[1]->type != EDGE_COPY_SRC_JOINER_BLOCK)
	{
	  edge e = (*path)[0]->e;
	  e->aux = (void *)path;
	  bitmap_set_bit (tmp, e->dest->index);
	}
    }

  /* Now iterate again, converting cases where we want to thread
     through a joiner block, but only if no other edge on the path
     already has a jump thread attached to it.  We do this in two passes,
     to avoid situations where the order in the paths vec can hide overlapping
     threads (the path is recorded on the incoming edge, so we would miss
     cases where the second path starts at a downstream edge on the same
     path).  First record all joiner paths, deleting any in the unexpected
     case where there is already a path for that incoming edge.  */
  for (i = 0; i < m_paths.length ();)
    {
      vec<jump_thread_edge *> *path = m_paths[i];

      if (path->length () > 1
	  && (*path)[1]->type == EDGE_COPY_SRC_JOINER_BLOCK)
	{
	  /* Attach the path to the starting edge if none is yet recorded.  */
	  if ((*path)[0]->e->aux == NULL)
	    {
	      (*path)[0]->e->aux = path;
	      i++;
	    }
	  else
	    {
	      m_paths.unordered_remove (i);
	      if (dump_file && (dump_flags & TDF_DETAILS))
		dump_jump_thread_path (dump_file, *path, false);
	      path->release ();
	    }
	}
      else
	{
	  i++;
	}
    }

  /* Second, look for paths that have any other jump thread attached to
     them, and either finish converting them or cancel them.  */
  for (i = 0; i < m_paths.length ();)
    {
      vec<jump_thread_edge *> *path = m_paths[i];
      edge e = (*path)[0]->e;

      if (path->length () > 1
	  && (*path)[1]->type == EDGE_COPY_SRC_JOINER_BLOCK && e->aux == path)
	{
	  unsigned int j;
	  for (j = 1; j < path->length (); j++)
	    if ((*path)[j]->e->aux != NULL)
	      break;

	  /* If we iterated through the entire path without exiting the loop,
	     then we are good to go, record it.  */
	  if (j == path->length ())
	    {
	      bitmap_set_bit (tmp, e->dest->index);
	      i++;
	    }
	  else
	    {
	      e->aux = NULL;
	      m_paths.unordered_remove (i);
	      if (dump_file && (dump_flags & TDF_DETAILS))
		dump_jump_thread_path (dump_file, *path, false);
	      path->release ();
	    }
	}
      else
	{
	  i++;
	}
    }

  /* When optimizing for size, prune all thread paths where statement
     duplication is necessary.

     We walk the jump thread path looking for copied blocks.  There's
     two types of copied blocks.

       EDGE_COPY_SRC_JOINER_BLOCK is always copied and thus we will
       cancel the jump threading request when optimizing for size.

       EDGE_COPY_SRC_BLOCK which is copied, but some of its statements
       will be killed by threading.  If threading does not kill all of
       its statements, then we should cancel the jump threading request
       when optimizing for size.  */
  if (optimize_function_for_size_p (cfun))
    {
      EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
	{
	  FOR_EACH_EDGE (e, ei, BASIC_BLOCK_FOR_FN (cfun, i)->preds)
	    if (e->aux)
	      {
		vec<jump_thread_edge *> *path = THREAD_PATH (e);

		unsigned int j;
		for (j = 1; j < path->length (); j++)
		  {
		    bb = (*path)[j]->e->src;
		    if (redirection_block_p (bb))
		      ;
		    else if ((*path)[j]->type == EDGE_COPY_SRC_JOINER_BLOCK
			     || ((*path)[j]->type == EDGE_COPY_SRC_BLOCK
			         && (count_stmts_and_phis_in_block (bb)
				     != estimate_threading_killed_stmts (bb))))
		      break;
		  }

		if (j != path->length ())
		  {
		    if (dump_file && (dump_flags & TDF_DETAILS))
		      dump_jump_thread_path (dump_file, *path, false);
		    path->release ();
		    e->aux = NULL;
		  }
		else
		  bitmap_set_bit (threaded_blocks, i);
	      }
	}
    }
  else
    bitmap_copy (threaded_blocks, tmp);

  /* If we have a joiner block (J) which has two successors S1 and S2 and
     we are threading though S1 and the final destination of the thread
     is S2, then we must verify that any PHI nodes in S2 have the same
     PHI arguments for the edge J->S2 and J->S1->...->S2.

     We used to detect this prior to registering the jump thread, but
     that prohibits propagation of edge equivalences into non-dominated
     PHI nodes as the equivalency test might occur before propagation.

     This must also occur after we truncate any jump threading paths
     as this scenario may only show up after truncation.

     This works for now, but will need improvement as part of the FSA
     optimization.

     Note since we've moved the thread request data to the edges,
     we have to iterate on those rather than the threaded_edges vector.  */
  EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
    {
      bb = BASIC_BLOCK_FOR_FN (cfun, i);
      FOR_EACH_EDGE (e, ei, bb->preds)
	{
	  if (e->aux)
	    {
	      vec<jump_thread_edge *> *path = THREAD_PATH (e);
	      bool have_joiner = ((*path)[1]->type == EDGE_COPY_SRC_JOINER_BLOCK);

	      if (have_joiner)
		{
		  basic_block joiner = e->dest;
		  edge final_edge = path->last ()->e;
		  basic_block final_dest = final_edge->dest;
		  edge e2 = find_edge (joiner, final_dest);

		  if (e2 && !phi_args_equal_on_edges (e2, final_edge))
		    {
		      path->release ();
		      e->aux = NULL;
		    }
		}
	    }
	}
    }

  /* Look for jump threading paths which cross multiple loop headers.

     The code to thread through loop headers will change the CFG in ways
     that invalidate the cached loop iteration information.  So we must
     detect that case and wipe the cached information.  */
  EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
    {
      basic_block bb = BASIC_BLOCK_FOR_FN (cfun, i);
      FOR_EACH_EDGE (e, ei, bb->preds)
	{
	  if (e->aux)
	    {
	      gcc_assert (loops_state_satisfies_p
			    (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS));
	      vec<jump_thread_edge *> *path = THREAD_PATH (e);

	      for (unsigned int i = 0, crossed_headers = 0;
		   i < path->length ();
		   i++)
		{
		  basic_block dest = (*path)[i]->e->dest;
		  basic_block src = (*path)[i]->e->src;
		  /* If we enter a loop.  */
		  if (flow_loop_nested_p (src->loop_father, dest->loop_father))
		    ++crossed_headers;
		  /* If we step from a block outside an irreducible region
		     to a block inside an irreducible region, then we have
		     crossed into a loop.  */
		  else if (! (src->flags & BB_IRREDUCIBLE_LOOP)
			   && (dest->flags & BB_IRREDUCIBLE_LOOP))
		      ++crossed_headers;
		  if (crossed_headers > 1)
		    {
		      vect_free_loop_info_assumptions
			((*path)[path->length () - 1]->e->dest->loop_father);
		      break;
		    }
		}
	    }
	}
    }
}


/* Verify that the REGION is a valid jump thread.  A jump thread is a special
   case of SEME Single Entry Multiple Exits region in which all nodes in the
   REGION have exactly one incoming edge.  The only exception is the first block
   that may not have been connected to the rest of the cfg yet.  */

DEBUG_FUNCTION void
verify_jump_thread (basic_block *region, unsigned n_region)
{
  for (unsigned i = 0; i < n_region; i++)
    gcc_assert (EDGE_COUNT (region[i]->preds) <= 1);
}

/* Return true when BB is one of the first N items in BBS.  */

static inline bool
bb_in_bbs (basic_block bb, basic_block *bbs, int n)
{
  for (int i = 0; i < n; i++)
    if (bb == bbs[i])
      return true;

  return false;
}

void
jump_thread_path_registry::debug_path (FILE *dump_file, int pathno)
{
  vec<jump_thread_edge *> *p = m_paths[pathno];
  fprintf (dump_file, "path: ");
  for (unsigned i = 0; i < p->length (); ++i)
    fprintf (dump_file, "%d -> %d, ",
	     (*p)[i]->e->src->index, (*p)[i]->e->dest->index);
  fprintf (dump_file, "\n");
}

void
jump_thread_path_registry::dump ()
{
  for (unsigned i = 0; i < m_paths.length (); ++i)
    debug_path (stderr, i);
}

/* Rewire a jump_thread_edge so that the source block is now a
   threaded source block.

   PATH_NUM is an index into the global path table PATHS.
   EDGE_NUM is the jump thread edge number into said path.

   Returns TRUE if we were able to successfully rewire the edge.  */

bool
jump_thread_path_registry::rewire_first_differing_edge (unsigned path_num,
							unsigned edge_num)
{
  vec<jump_thread_edge *> *path = m_paths[path_num];
  edge &e = (*path)[edge_num]->e;
  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "rewiring edge candidate: %d -> %d\n",
	     e->src->index, e->dest->index);
  basic_block src_copy = get_bb_copy (e->src);
  if (src_copy == NULL)
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "ignoring candidate: there is no src COPY\n");
      return false;
    }
  edge new_edge = find_edge (src_copy, e->dest);
  /* If the previously threaded paths created a flow graph where we
     can no longer figure out where to go, give up.  */
  if (new_edge == NULL)
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "ignoring candidate: we lost our way\n");
      return false;
    }
  e = new_edge;
  return true;
}

/* After an FSM path has been jump threaded, adjust the remaining FSM
   paths that are subsets of this path, so these paths can be safely
   threaded within the context of the new threaded path.

   For example, suppose we have just threaded:

   5 -> 6 -> 7 -> 8 -> 12	=>	5 -> 6' -> 7' -> 8' -> 12'

   And we have an upcoming threading candidate:
   5 -> 6 -> 7 -> 8 -> 15 -> 20

   This function adjusts the upcoming path into:
   8' -> 15 -> 20

   CURR_PATH_NUM is an index into the global paths table.  It
   specifies the path that was just threaded.  */

void
jump_thread_path_registry::adjust_paths_after_duplication
	(unsigned curr_path_num)
{
  vec<jump_thread_edge *> *curr_path = m_paths[curr_path_num];
  gcc_assert ((*curr_path)[0]->type == EDGE_FSM_THREAD);

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "just threaded: ");
      debug_path (dump_file, curr_path_num);
    }

  /* Iterate through all the other paths and adjust them.  */
  for (unsigned cand_path_num = 0; cand_path_num < m_paths.length (); )
    {
      if (cand_path_num == curr_path_num)
	{
	  ++cand_path_num;
	  continue;
	}
      /* Make sure the candidate to adjust starts with the same path
	 as the recently threaded path and is an FSM thread.  */
      vec<jump_thread_edge *> *cand_path = m_paths[cand_path_num];
      if ((*cand_path)[0]->type != EDGE_FSM_THREAD
	  || (*cand_path)[0]->e != (*curr_path)[0]->e)
	{
	  ++cand_path_num;
	  continue;
	}
      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "adjusting candidate: ");
	  debug_path (dump_file, cand_path_num);
	}

      /* Chop off from the candidate path any prefix it shares with
	 the recently threaded path.  */
      unsigned minlength = MIN (curr_path->length (), cand_path->length ());
      unsigned j;
      for (j = 0; j < minlength; ++j)
	{
	  edge cand_edge = (*cand_path)[j]->e;
	  edge curr_edge = (*curr_path)[j]->e;

	  /* Once the prefix no longer matches, adjust the first
	     non-matching edge to point from an adjusted edge to
	     wherever it was going.  */
	  if (cand_edge != curr_edge)
	    {
	      gcc_assert (cand_edge->src == curr_edge->src);
	      if (!rewire_first_differing_edge (cand_path_num, j))
		goto remove_candidate_from_list;
	      break;
	    }
	}
      if (j == minlength)
	{
	  /* If we consumed the max subgraph we could look at, and
	     still didn't find any different edges, it's the
	     last edge after MINLENGTH.  */
	  if (cand_path->length () > minlength)
	    {
	      if (!rewire_first_differing_edge (cand_path_num, j))
		goto remove_candidate_from_list;
	    }
	  else if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file, "adjusting first edge after MINLENGTH.\n");
	}
      if (j > 0)
	{
	  /* If we are removing everything, delete the entire candidate.  */
	  if (j == cand_path->length ())
	    {
	    remove_candidate_from_list:
	      if (dump_file && (dump_flags & TDF_DETAILS))
		fprintf (dump_file, "adjusted candidate: [EMPTY]\n");
	      cand_path->release ();
	      m_paths.unordered_remove (cand_path_num);
	      continue;
	    }
	  /* Otherwise, just remove the redundant sub-path.  */
	  cand_path->block_remove (0, j);
	}
      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "adjusted candidate: ");
	  debug_path (dump_file, cand_path_num);
	}
      ++cand_path_num;
    }
}

/* Duplicates a jump-thread path of N_REGION basic blocks.
   The ENTRY edge is redirected to the duplicate of the region.

   Remove the last conditional statement in the last basic block in the REGION,
   and create a single fallthru edge pointing to the same destination as the
   EXIT edge.

   CURRENT_PATH_NO is an index into the global paths[] table
   specifying the jump-thread path.

   Returns false if it is unable to copy the region, true otherwise.  */

bool
jump_thread_path_registry::duplicate_thread_path (edge entry,
						  edge exit,
						  basic_block *region,
						  unsigned n_region,
						  unsigned current_path_no)
{
  unsigned i;
  class loop *loop = entry->dest->loop_father;
  edge exit_copy;
  edge redirected;
  profile_count curr_count;

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

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "\nabout to thread: ");
      debug_path (dump_file, current_path_no);
    }

  /* 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;
    }

  initialize_original_copy_tables ();

  set_loop_copy (loop, loop);

  basic_block *region_copy = XNEWVEC (basic_block, n_region);
  copy_bbs (region, n_region, region_copy, &exit, 1, &exit_copy, loop,
	    split_edge_bb_loc (entry), false);

  /* Fix up: copy_bbs redirects all edges pointing to copied blocks.  The
     following code ensures that all the edges exiting the jump-thread path are
     redirected back to the original code: these edges are exceptions
     invalidating the property that is propagated by executing all the blocks of
     the jump-thread path in order.  */

  curr_count = entry->count ();

  for (i = 0; i < n_region; i++)
    {
      edge e;
      edge_iterator ei;
      basic_block bb = region_copy[i];

      /* Watch inconsistent profile.  */
      if (curr_count > region[i]->count)
	curr_count = region[i]->count;
      /* Scale current BB.  */
      if (region[i]->count.nonzero_p () && curr_count.initialized_p ())
	{
	  /* In the middle of the path we only scale the frequencies.
	     In last BB we need to update probabilities of outgoing edges
	     because we know which one is taken at the threaded path.  */
	  if (i + 1 != n_region)
	    scale_bbs_frequencies_profile_count (region + i, 1,
					         region[i]->count - curr_count,
					         region[i]->count);
	  else
	    update_bb_profile_for_threading (region[i],
					     curr_count,
					     exit);
	  scale_bbs_frequencies_profile_count (region_copy + i, 1, curr_count,
					       region_copy[i]->count);
	}

      if (single_succ_p (bb))
	{
	  /* Make sure the successor is the next node in the path.  */
	  gcc_assert (i + 1 == n_region
		      || region_copy[i + 1] == single_succ_edge (bb)->dest);
	  if (i + 1 != n_region)
	    {
	      curr_count = single_succ_edge (bb)->count ();
	    }
	  continue;
	}

      /* Special case the last block on the path: make sure that it does not
	 jump back on the copied path, including back to itself.  */
      if (i + 1 == n_region)
	{
	  FOR_EACH_EDGE (e, ei, bb->succs)
	    if (bb_in_bbs (e->dest, region_copy, n_region))
	      {
		basic_block orig = get_bb_original (e->dest);
		if (orig)
		  redirect_edge_and_branch_force (e, orig);
	      }
	  continue;
	}

      /* Redirect all other edges jumping to non-adjacent blocks back to the
	 original code.  */
      FOR_EACH_EDGE (e, ei, bb->succs)
	if (region_copy[i + 1] != e->dest)
	  {
	    basic_block orig = get_bb_original (e->dest);
	    if (orig)
	      redirect_edge_and_branch_force (e, orig);
	  }
	else
	  {
	    curr_count = e->count ();
	  }
    }


  if (flag_checking)
    verify_jump_thread (region_copy, n_region);

  /* Remove the last branch in the jump thread path.  */
  remove_ctrl_stmt_and_useless_edges (region_copy[n_region - 1], exit->dest);

  /* And fixup the flags on the single remaining edge.  */
  edge fix_e = find_edge (region_copy[n_region - 1], exit->dest);
  fix_e->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE | EDGE_ABNORMAL);
  fix_e->flags |= EDGE_FALLTHRU;

  edge e = make_edge (region_copy[n_region - 1], exit->dest, EDGE_FALLTHRU);

  if (e)
    {
      rescan_loop_exit (e, true, false);
      e->probability = profile_probability::always ();
    }

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

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

  free (region_copy);

  adjust_paths_after_duplication (current_path_no);

  free_original_copy_tables ();
  return true;
}

/* Return true when PATH is a valid jump-thread path.  */

static bool
valid_jump_thread_path (vec<jump_thread_edge *> *path)
{
  unsigned len = path->length ();

  /* Check that the path is connected.  */
  for (unsigned int j = 0; j < len - 1; j++)
    {
      edge e = (*path)[j]->e;
      if (e->dest != (*path)[j+1]->e->src)
	return false;
    }
  return true;
}

/* Remove any queued jump threads that include edge E.

   We don't actually remove them here, just record the edges into ax
   hash table.  That way we can do the search once per iteration of
   DOM/VRP rather than for every case where DOM optimizes away a COND_EXPR.  */

void
jump_thread_path_registry::remove_jump_threads_including (edge_def *e)
{
  if (!m_paths.exists ())
    return;

  edge *slot = m_removed_edges->find_slot (e, INSERT);
  *slot = e;
}

/* Walk through all blocks and thread incoming edges to the appropriate
   outgoing edge for each edge pair recorded in THREADED_EDGES.

   It is the caller's responsibility to fix the dominance information
   and rewrite duplicated SSA_NAMEs back into SSA form.

   If MAY_PEEL_LOOP_HEADERS is false, we avoid threading edges through
   loop headers if it does not simplify the loop.

   Returns true if one or more edges were threaded, false otherwise.  */

bool
jump_thread_path_registry::thread_through_all_blocks
	(bool may_peel_loop_headers)
{
  bool retval = false;
  unsigned int i;
  class loop *loop;
  auto_bitmap threaded_blocks;
  hash_set<edge> visited_starting_edges;

  if (!m_paths.exists ())
    {
      retval = false;
      goto out;
    }

  m_num_threaded_edges = 0;

  /* Remove any paths that referenced removed edges.  */
  if (m_removed_edges)
    for (i = 0; i < m_paths.length (); )
      {
	unsigned int j;
	vec<jump_thread_edge *> *path = m_paths[i];

	for (j = 0; j < path->length (); j++)
	  {
	    edge e = (*path)[j]->e;
	    if (m_removed_edges->find_slot (e, NO_INSERT))
	      break;
	  }

	if (j != path->length ())
	  {
	    path->release ();
	    m_paths.unordered_remove (i);
	    continue;
	  }
	i++;
      }

  /* Jump-thread all FSM threads before other jump-threads.  */
  for (i = 0; i < m_paths.length ();)
    {
      vec<jump_thread_edge *> *path = m_paths[i];
      edge entry = (*path)[0]->e;

      /* Only code-generate FSM jump-threads in this loop.  */
      if ((*path)[0]->type != EDGE_FSM_THREAD)
	{
	  i++;
	  continue;
	}

      /* Do not jump-thread twice from the same starting edge.

	 Previously we only checked that we weren't threading twice
	 from the same BB, but that was too restrictive.  Imagine a
	 path that starts from GIMPLE_COND(x_123 == 0,...), where both
	 edges out of this conditional yield paths that can be
	 threaded (for example, both lead to an x_123==0 or x_123!=0
	 conditional further down the line.  */
      if (visited_starting_edges.contains (entry)
	  /* We may not want to realize this jump thread path for
	     various reasons.  So check it first.  */
	  || !valid_jump_thread_path (path))
	{
	  /* Remove invalid FSM jump-thread paths.  */
	  path->release ();
	  m_paths.unordered_remove (i);
	  continue;
	}

      unsigned len = path->length ();
      edge exit = (*path)[len - 1]->e;
      basic_block *region = XNEWVEC (basic_block, len - 1);

      for (unsigned int j = 0; j < len - 1; j++)
	region[j] = (*path)[j]->e->dest;

      if (duplicate_thread_path (entry, exit, region, len - 1, i))
	{
	  /* We do not update dominance info.  */
	  free_dominance_info (CDI_DOMINATORS);
	  visited_starting_edges.add (entry);
	  retval = true;
	  m_num_threaded_edges++;
	}

      path->release ();
      m_paths.unordered_remove (i);
      free (region);
    }

  /* Remove from PATHS all the jump-threads starting with an edge already
     jump-threaded.  */
  for (i = 0; i < m_paths.length ();)
    {
      vec<jump_thread_edge *> *path = m_paths[i];
      edge entry = (*path)[0]->e;

      /* Do not jump-thread twice from the same block.  */
      if (visited_starting_edges.contains (entry))
	{
	  path->release ();
	  m_paths.unordered_remove (i);
	}
      else
	i++;
    }

  mark_threaded_blocks (threaded_blocks);

  initialize_original_copy_tables ();

  /* The order in which we process jump threads can be important.

     Consider if we have two jump threading paths A and B.  If the
     target edge of A is the starting edge of B and we thread path A
     first, then we create an additional incoming edge into B->dest that
     we cannot discover as a jump threading path on this iteration.

     If we instead thread B first, then the edge into B->dest will have
     already been redirected before we process path A and path A will
     natually, with no further work, target the redirected path for B.

     An post-order is sufficient here.  Compute the ordering first, then
     process the blocks.  */
  if (!bitmap_empty_p (threaded_blocks))
    {
      int *postorder = XNEWVEC (int, n_basic_blocks_for_fn (cfun));
      unsigned int postorder_num = post_order_compute (postorder, false, false);
      for (unsigned int i = 0; i < postorder_num; i++)
	{
	  unsigned int indx = postorder[i];
	  if (bitmap_bit_p (threaded_blocks, indx))
	    {
	      basic_block bb = BASIC_BLOCK_FOR_FN (cfun, indx);
	      retval |= thread_block (bb, true);
	    }
	}
      free (postorder);
    }

  /* Then perform the threading through loop headers.  We start with the
     innermost loop, so that the changes in cfg we perform won't affect
     further threading.  */
  FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
    {
      if (!loop->header
	  || !bitmap_bit_p (threaded_blocks, loop->header->index))
	continue;

      retval |= thread_through_loop_header (loop, may_peel_loop_headers);
    }

  /* All jump threading paths should have been resolved at this
     point.  Verify that is the case.  */
  basic_block bb;
  FOR_EACH_BB_FN (bb, cfun)
    {
      edge_iterator ei;
      edge e;
      FOR_EACH_EDGE (e, ei, bb->preds)
	gcc_assert (e->aux == NULL);
    }

  statistics_counter_event (cfun, "Jumps threaded", m_num_threaded_edges);

  free_original_copy_tables ();

  m_paths.release ();

  if (retval)
    loops_state_set (LOOPS_NEED_FIXUP);

 out:
  return retval;
}

/* Register a jump threading opportunity.  We queue up all the jump
   threading opportunities discovered by a pass and update the CFG
   and SSA form all at once.

   E is the edge we can thread, E2 is the new target edge, i.e., we
   are effectively recording that E->dest can be changed to E2->dest
   after fixing the SSA graph.  */

void
jump_thread_path_registry::register_jump_thread (vec<jump_thread_edge *> *path)
{
  if (!dbg_cnt (registered_jump_thread))
    {
      path->release ();
      return;
    }

  /* First make sure there are no NULL outgoing edges on the jump threading
     path.  That can happen for jumping to a constant address.  */
  for (unsigned int i = 0; i < path->length (); i++)
    {
      if ((*path)[i]->e == NULL)
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file,
		       "Found NULL edge in jump threading path.  Cancelling jump thread:\n");
	      dump_jump_thread_path (dump_file, *path, false);
	    }

	  path->release ();
	  return;
	}

      /* Only the FSM threader is allowed to thread across
	 backedges in the CFG.  */
      if (flag_checking
	  && (*path)[0]->type != EDGE_FSM_THREAD)
	gcc_assert (((*path)[i]->e->flags & EDGE_DFS_BACK) == 0);
    }

  if (dump_file && (dump_flags & TDF_DETAILS))
    dump_jump_thread_path (dump_file, *path, true);

  m_paths.safe_push (path);
}

/* Return how many uses of T there are within BB, as long as there
   aren't any uses outside BB.  If there are any uses outside BB,
   return -1 if there's at most one use within BB, or -2 if there is
   more than one use within BB.  */

static int
uses_in_bb (tree t, basic_block bb)
{
  int uses = 0;
  bool outside_bb = false;

  imm_use_iterator iter;
  use_operand_p use_p;
  FOR_EACH_IMM_USE_FAST (use_p, iter, t)
    {
      if (is_gimple_debug (USE_STMT (use_p)))
	continue;

      if (gimple_bb (USE_STMT (use_p)) != bb)
	outside_bb = true;
      else
	uses++;

      if (outside_bb && uses > 1)
	return -2;
    }

  if (outside_bb)
    return -1;

  return uses;
}

/* Starting from the final control flow stmt in BB, assuming it will
   be removed, follow uses in to-be-removed stmts back to their defs
   and count how many defs are to become dead and be removed as
   well.  */

unsigned int
estimate_threading_killed_stmts (basic_block bb)
{
  int killed_stmts = 0;
  hash_map<tree, int> ssa_remaining_uses;
  auto_vec<gimple *, 4> dead_worklist;

  /* If the block has only two predecessors, threading will turn phi
     dsts into either src, so count them as dead stmts.  */
  bool drop_all_phis = EDGE_COUNT (bb->preds) == 2;

  if (drop_all_phis)
    for (gphi_iterator gsi = gsi_start_phis (bb);
	 !gsi_end_p (gsi); gsi_next (&gsi))
      {
	gphi *phi = gsi.phi ();
	tree dst = gimple_phi_result (phi);

	/* We don't count virtual PHIs as stmts in
	   record_temporary_equivalences_from_phis.  */
	if (virtual_operand_p (dst))
	  continue;

	killed_stmts++;
      }

  if (gsi_end_p (gsi_last_bb (bb)))
    return killed_stmts;

  gimple *stmt = gsi_stmt (gsi_last_bb (bb));
  if (gimple_code (stmt) != GIMPLE_COND
      && gimple_code (stmt) != GIMPLE_GOTO
      && gimple_code (stmt) != GIMPLE_SWITCH)
    return killed_stmts;

  /* The control statement is always dead.  */
  killed_stmts++;
  dead_worklist.quick_push (stmt);
  while (!dead_worklist.is_empty ())
    {
      stmt = dead_worklist.pop ();

      ssa_op_iter iter;
      use_operand_p use_p;
      FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
	{
	  tree t = USE_FROM_PTR (use_p);
	  gimple *def = SSA_NAME_DEF_STMT (t);

	  if (gimple_bb (def) == bb
	      && (gimple_code (def) != GIMPLE_PHI
		  || !drop_all_phis)
	      && !gimple_has_side_effects (def))
	    {
	      int *usesp = ssa_remaining_uses.get (t);
	      int uses;

	      if (usesp)
		uses = *usesp;
	      else
		uses = uses_in_bb (t, bb);

	      gcc_assert (uses);

	      /* Don't bother recording the expected use count if we
		 won't find any further uses within BB.  */
	      if (!usesp && (uses < -1 || uses > 1))
		{
		  usesp = &ssa_remaining_uses.get_or_insert (t);
		  *usesp = uses;
		}

	      if (uses < 0)
		continue;

	      --uses;
	      if (usesp)
		*usesp = uses;

	      if (!uses)
		{
		  killed_stmts++;
		  if (usesp)
		    ssa_remaining_uses.remove (t);
		  if (gimple_code (def) != GIMPLE_PHI)
		    dead_worklist.safe_push (def);
		}
	    }
	}
    }

  if (dump_file)
    fprintf (dump_file, "threading bb %i kills %i stmts\n",
	     bb->index, killed_stmts);

  return killed_stmts;
}
