/* SSA Jump Threading
   Copyright (C) 2005-2022 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 "predict.h"
#include "tree.h"
#include "gimple.h"
#include "fold-const.h"
#include "cfgloop.h"
#include "gimple-iterator.h"
#include "tree-cfg.h"
#include "tree-ssa-threadupdate.h"
#include "tree-ssa-loop.h"
#include "cfganal.h"
#include "tree-pass.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
#include "tree-inline.h"
#include "tree-vectorizer.h"
#include "value-range.h"
#include "gimple-range.h"
#include "tree-ssa-threadedge.h"
#include "gimple-range-path.h"
#include "ssa.h"
#include "tree-cfgcleanup.h"
#include "tree-pretty-print.h"
#include "cfghooks.h"
#include "dbgcnt.h"

// Path registry for the backwards threader.  After all paths have been
// registered with register_path(), thread_through_all_blocks() is called
// to modify the CFG.

class back_threader_registry : public back_jt_path_registry
{
public:
  bool register_path (const vec<basic_block> &, edge taken);
};

// Class to abstract the profitability code for the backwards threader.

class back_threader_profitability
{
public:
  back_threader_profitability (bool speed_p, gimple *stmt);
  bool possibly_profitable_path_p (const vec<basic_block> &, tree, bool *);
  bool profitable_path_p (const vec<basic_block> &,
			  edge taken, bool *irreducible_loop);
private:
  const bool m_speed_p;
  int m_exit_jump_benefit;
  bool m_threaded_multiway_branch;
  // The following are computed by possibly_profitable_path_p
  bool m_threaded_through_latch;
  bool m_multiway_branch_in_path;
  bool m_contains_hot_bb;
  int m_n_insns;
};

back_threader_profitability::back_threader_profitability (bool speed_p,
							  gimple *last)
  : m_speed_p (speed_p)
{
  m_threaded_multiway_branch = (gimple_code (last) == GIMPLE_SWITCH
				|| gimple_code (last) == GIMPLE_GOTO);
  // The forward threader has estimate_threading_killed_stmts, in
  // particular it estimates further DCE from eliminating the exit
  // control stmt.
  m_exit_jump_benefit = estimate_num_insns (last, &eni_size_weights);
}

// Back threader flags.
#define BT_NONE 0
// Generate fast code at the expense of code size.
#define BT_SPEED 1
// Resolve unknown SSAs on entry to a threading path.  If set, use the
// ranger.  If not, assume all ranges on entry to a path are VARYING.
#define BT_RESOLVE 2

class back_threader
{
public:
  back_threader (function *fun, unsigned flags, bool first);
  ~back_threader ();
  unsigned thread_blocks ();
private:
  void maybe_thread_block (basic_block bb);
  bool debug_counter ();
  edge maybe_register_path (back_threader_profitability &);
  void maybe_register_path_dump (edge taken_edge);
  void find_paths_to_names (basic_block bb, bitmap imports, unsigned,
			    back_threader_profitability &);
  edge find_taken_edge (const vec<basic_block> &path);
  edge find_taken_edge_cond (const vec<basic_block> &path, gcond *);
  edge find_taken_edge_switch (const vec<basic_block> &path, gswitch *);
  virtual void debug ();
  virtual void dump (FILE *out);

  back_threader_registry m_registry;

  // Current path being analyzed.
  auto_vec<basic_block> m_path;
  // Hash to mark visited BBs while analyzing a path.
  hash_set<basic_block> m_visited_bbs;
  // The set of SSA names, any of which could potentially change the
  // value of the final conditional in a path.
  auto_bitmap m_imports;
  // The last statement in the path.
  gimple *m_last_stmt;
  // This is a bit of a wart.  It's used to pass the LHS SSA name to
  // the profitability engine.
  tree m_name;
  // Marker to differentiate unreachable edges.
  static const edge UNREACHABLE_EDGE;
  // Set to TRUE if unknown SSA names along a path should be resolved
  // with the ranger.  Otherwise, unknown SSA names are assumed to be
  // VARYING.  Setting to true is more precise but slower.
  function *m_fun;
  // Ranger for the path solver.
  gimple_ranger *m_ranger;
  unsigned m_flags;
  // Set to TRUE for the first of each thread[12] pass or the first of
  // each threadfull[12] pass.  This is used to differentiate between
  // the different threading passes so we can set up debug counters.
  bool m_first;
};

// Used to differentiate unreachable edges, so we may stop the search
// in a the given direction.
const edge back_threader::UNREACHABLE_EDGE = (edge) -1;

back_threader::back_threader (function *fun, unsigned flags, bool first)
  : m_first (first)
{
  if (flags & BT_SPEED)
    loop_optimizer_init (LOOPS_HAVE_PREHEADERS | LOOPS_HAVE_SIMPLE_LATCHES);
  else
    loop_optimizer_init (AVOID_CFG_MODIFICATIONS);

  m_fun = fun;
  m_flags = flags;
  m_last_stmt = NULL;

  // The path solver needs EDGE_DFS_BACK in resolving mode.
  if (flags & BT_RESOLVE)
    mark_dfs_back_edges ();

  m_ranger = new gimple_ranger;
}

back_threader::~back_threader ()
{
  delete m_ranger;
  loop_optimizer_finalize ();
}

// A wrapper for the various debug counters for the threading passes.
// Returns TRUE if it's OK to register the current threading
// candidate.

bool
back_threader::debug_counter ()
{
  // The ethread pass is mostly harmless ;-).
  if ((m_flags & BT_SPEED) == 0)
    return true;

  if (m_flags & BT_RESOLVE)
    {
      if (m_first && !dbg_cnt (back_threadfull1))
	return false;

      if (!m_first && !dbg_cnt (back_threadfull2))
	return false;
    }
  else
    {
      if (m_first && !dbg_cnt (back_thread1))
	return false;

      if (!m_first && !dbg_cnt (back_thread2))
	return false;
    }
  return true;
}

static void
dump_path (FILE *dump_file, const vec<basic_block> &path)
{
  for (unsigned i = path.length (); i > 0; --i)
    {
      basic_block bb = path[i - 1];
      fprintf (dump_file, "%d", bb->index);
      if (i > 1)
	fprintf (dump_file, "->");
    }
}

// Dump details of an attempt to register a path.

void
back_threader::maybe_register_path_dump (edge taken)
{
  if (m_path.is_empty ())
    return;

  fprintf (dump_file, "path: ");
  dump_path (dump_file, m_path);
  fprintf (dump_file, "->");

  if (taken == UNREACHABLE_EDGE)
    fprintf (dump_file, "xx REJECTED (unreachable)\n");
  else if (taken)
    fprintf (dump_file, "%d SUCCESS\n", taken->dest->index);
  else
    fprintf (dump_file, "xx REJECTED\n");
}

// If an outgoing edge can be determined out of the current path,
// register it for jump threading and return the taken edge.
//
// Return NULL if it is unprofitable to thread this path, or the
// outgoing edge is unknown.  Return UNREACHABLE_EDGE if the path is
// unreachable.

edge
back_threader::maybe_register_path (back_threader_profitability &profit)
{
  edge taken_edge = find_taken_edge (m_path);

  if (taken_edge && taken_edge != UNREACHABLE_EDGE)
    {
      bool irreducible = false;
      if (profit.profitable_path_p (m_path, taken_edge, &irreducible)
	  && debug_counter ()
	  && m_registry.register_path (m_path, taken_edge))
	{
	  if (irreducible)
	    vect_free_loop_info_assumptions (m_path[0]->loop_father);
	}
      else
	taken_edge = NULL;
    }

  if (dump_file && (dump_flags & TDF_DETAILS))
    maybe_register_path_dump (taken_edge);

  return taken_edge;
}

// Return the known taken edge out of a path.  If the path can be
// determined to be unreachable, return UNREACHABLE_EDGE.  If no
// outgoing edge can be calculated, return NULL.

edge
back_threader::find_taken_edge (const vec<basic_block> &path)
{
  gcc_checking_assert (path.length () > 1);
  switch (gimple_code (m_last_stmt))
    {
    case GIMPLE_COND:
      return find_taken_edge_cond (path, as_a<gcond *> (m_last_stmt));

    case GIMPLE_SWITCH:
      return find_taken_edge_switch (path, as_a<gswitch *> (m_last_stmt));

    default:
      return NULL;
    }
}

// Same as find_taken_edge, but for paths ending in a switch.

edge
back_threader::find_taken_edge_switch (const vec<basic_block> &path,
				       gswitch *sw)
{
  tree name = gimple_switch_index (sw);
  int_range_max r;

  path_range_query solver (*m_ranger, path, m_imports, m_flags & BT_RESOLVE);
  solver.range_of_expr (r, name, sw);

  if (r.undefined_p ())
    return UNREACHABLE_EDGE;

  if (r.varying_p ())
    return NULL;

  tree label = find_case_label_range (sw, &r);
  if (!label)
    return NULL;

  return find_edge (gimple_bb (sw), label_to_block (cfun, CASE_LABEL (label)));
}

// Same as find_taken_edge, but for paths ending in a GIMPLE_COND.

edge
back_threader::find_taken_edge_cond (const vec<basic_block> &path,
				     gcond *cond)
{
  int_range_max r;

  path_range_query solver (*m_ranger, path, m_imports, m_flags & BT_RESOLVE);
  solver.range_of_stmt (r, cond);

  if (solver.unreachable_path_p ())
    return UNREACHABLE_EDGE;

  int_range<2> true_range (boolean_true_node, boolean_true_node);
  int_range<2> false_range (boolean_false_node, boolean_false_node);

  if (r == true_range || r == false_range)
    {
      edge e_true, e_false;
      basic_block bb = gimple_bb (cond);
      extract_true_false_edges_from_block (bb, &e_true, &e_false);
      return r == true_range ? e_true : e_false;
    }
  return NULL;
}

// Find jump threading paths to any of the SSA names in the
// INTERESTING bitmap, and register any such paths.
//
// BB is the current path being processed.
//
// OVERALL_PATHS is the search space up to this block

void
back_threader::find_paths_to_names (basic_block bb, bitmap interesting,
				    unsigned overall_paths,
				    back_threader_profitability &profit)
{
  if (m_visited_bbs.add (bb))
    return;

  m_path.safe_push (bb);

  // Try to resolve the path without looking back.  Avoid resolving paths
  // we know are large but are not (yet) recognized as Finite State Machine.
  // ???  Ideally we'd explore the cheapest path to the loop backedge here,
  // avoiding the exponential greedy search and only start that from there.
  // Precomputing a path-size-to-immediate-dominator-of-successor for each
  // edge might help here.  Alternatively copying divergent control flow
  // on the way to the backedge could be worthwhile.
  bool large_non_fsm;
  if (m_path.length () > 1
      && (!profit.possibly_profitable_path_p (m_path, m_name, &large_non_fsm)
	  || (!large_non_fsm
	      && maybe_register_path (profit))))
    ;

  // The backwards thread copier cannot copy blocks that do not belong
  // to the same loop, so when the new source of the path entry no
  // longer belongs to it we don't need to search further.
  else if (m_path[0]->loop_father != bb->loop_father)
    ;

  // Continue looking for ways to extend the path but limit the
  // search space along a branch
  else if ((overall_paths = overall_paths * EDGE_COUNT (bb->preds))
	   <= (unsigned)param_max_jump_thread_paths)
    {
      // For further greedy searching we want to remove interesting
      // names defined in BB but add ones on the PHI edges for the
      // respective edges and adding imports from those stmts.
      // We do this by starting with all names
      // not defined in BB as interesting, collecting a list of
      // interesting PHIs in BB on the fly.  Then we iterate over
      // predecessor edges, adding interesting PHI edge defs to
      // the set of interesting names to consider when processing it.
      auto_bitmap new_interesting;
      auto_vec<int, 16> new_imports;
      auto_vec<gphi *, 4> interesting_phis;
      bitmap_iterator bi;
      unsigned i;
      auto_vec<tree, 16> worklist;
      EXECUTE_IF_SET_IN_BITMAP (interesting, 0, i, bi)
	{
	  tree name = ssa_name (i);
	  gimple *def_stmt = SSA_NAME_DEF_STMT (name);
	  /* Imports remain interesting.  */
	  if (gimple_bb (def_stmt) != bb)
	    {
	      bitmap_set_bit (new_interesting, i);
	      continue;
	    }
	  worklist.quick_push (name);
	  while (!worklist.is_empty ())
	    {
	      tree name = worklist.pop ();
	      gimple *def_stmt = SSA_NAME_DEF_STMT (name);
	      /* Newly discovered imports are interesting.  */
	      if (gimple_bb (def_stmt) != bb)
		{
		  bitmap_set_bit (new_interesting, SSA_NAME_VERSION (name));
		  continue;
		}
	      /* Local PHIs participate in renaming below.  */
	      if (gphi *phi = dyn_cast<gphi *> (def_stmt))
		{
		  tree res = gimple_phi_result (phi);
		  if (!SSA_NAME_OCCURS_IN_ABNORMAL_PHI (res))
		    interesting_phis.safe_push (phi);
		}
	      /* For other local defs process their uses, amending
		 imports on the way.  */
	      else
		{
		  tree ssa[3];
		  unsigned lim = gimple_range_ssa_names (ssa, 3, def_stmt);
		  for (unsigned j = 0; j < lim; ++j)
		    {
		      tree rhs = ssa[j];
		      if (rhs
			  && bitmap_set_bit (m_imports,
					     SSA_NAME_VERSION (rhs)))
			{
			  new_imports.safe_push (SSA_NAME_VERSION (rhs));
			  worklist.safe_push (rhs);
			}
		    }
		}
	    }
	}
      if (!bitmap_empty_p (new_interesting)
	  || !interesting_phis.is_empty ())
	{
	  auto_vec<int, 4> unwind (interesting_phis.length ());
	  auto_vec<int, 4> imports_unwind (interesting_phis.length ());
	  edge_iterator iter;
	  edge e;
	  FOR_EACH_EDGE (e, iter, bb->preds)
	    {
	      if (e->flags & EDGE_ABNORMAL
		  // This is like path_crosses_loops in profitable_path_p but
		  // more restrictive to avoid peeling off loop iterations (see
		  // tree-ssa/pr14341.c for an example).
		  // ???  Note this restriction only applied when visiting an
		  // interesting PHI with the former resolve_phi.
		  || (!interesting_phis.is_empty ()
		      && m_path[0]->loop_father != e->src->loop_father))
		continue;
	      for (gphi *phi : interesting_phis)
		{
		  tree def = PHI_ARG_DEF_FROM_EDGE (phi, e);
		  if (TREE_CODE (def) == SSA_NAME)
		    {
		      int ver = SSA_NAME_VERSION (def);
		      if (bitmap_set_bit (new_interesting, ver))
			{
			  if (bitmap_set_bit (m_imports, ver))
			    imports_unwind.quick_push (ver);
			  unwind.quick_push (ver);
			}
		    }
		}
	      find_paths_to_names (e->src, new_interesting, overall_paths,
				   profit);
	      // Restore new_interesting.
	      for (int def : unwind)
		bitmap_clear_bit (new_interesting, def);
	      unwind.truncate (0);
	      // Restore and m_imports.
	      for (int def : imports_unwind)
		bitmap_clear_bit (m_imports, def);
	      imports_unwind.truncate (0);
	    }
	}
      /* m_imports tracks all interesting names on the path, so when
	 backtracking we have to restore it.  */
      for (int j : new_imports)
	bitmap_clear_bit (m_imports, j);
    }
  else if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "  FAIL: Search space limit %d reached.\n",
	     param_max_jump_thread_paths);

  // Reset things to their original state.
  m_path.pop ();
  m_visited_bbs.remove (bb);
}

// Search backwards from BB looking for paths where the final
// conditional maybe threaded to a successor block.  Record such paths
// for jump threading.

void
back_threader::maybe_thread_block (basic_block bb)
{
  if (EDGE_COUNT (bb->succs) <= 1)
    return;

  gimple *stmt = last_stmt (bb);
  if (!stmt)
    return;

  enum gimple_code code = gimple_code (stmt);
  tree name;
  if (code == GIMPLE_SWITCH)
    name = gimple_switch_index (as_a <gswitch *> (stmt));
  else if (code == GIMPLE_COND)
    name = gimple_cond_lhs (stmt);
  else
    return;

  m_last_stmt = stmt;
  m_visited_bbs.empty ();
  m_path.truncate (0);
  m_name = name;

  // We compute imports of the path during discovery starting
  // just with names used in the conditional.
  bitmap_clear (m_imports);
  ssa_op_iter iter;
  FOR_EACH_SSA_TREE_OPERAND (name, stmt, iter, SSA_OP_USE)
    {
      if (!gimple_range_ssa_p (name))
	return;
      bitmap_set_bit (m_imports, SSA_NAME_VERSION (name));
    }

  // Interesting is the set of imports we still not have see
  // the definition of.  So while imports only grow, the
  // set of interesting defs dwindles and once empty we can
  // stop searching.
  auto_bitmap interesting;
  bitmap_copy (interesting, m_imports);
  back_threader_profitability profit (m_flags & BT_SPEED, stmt);
  find_paths_to_names (bb, interesting, 1, profit);
}

DEBUG_FUNCTION void
debug (const vec <basic_block> &path)
{
  dump_path (stderr, path);
  fputc ('\n', stderr);
}

void
back_threader::dump (FILE *out)
{
  fprintf (out, "\nCandidates for pre-computation:\n");
  fprintf (out, "===================================\n");

  bitmap_iterator bi;
  unsigned i;

  EXECUTE_IF_SET_IN_BITMAP (m_imports, 0, i, bi)
    {
      tree name = ssa_name (i);
      print_generic_expr (out, name, TDF_NONE);
      fprintf (out, "\n");
    }
}

void
back_threader::debug ()
{
  dump (stderr);
}

/* Examine jump threading path PATH and return TRUE if it is possibly
   profitable to thread it, otherwise return FALSE.  If this function
   returns TRUE profitable_path_p might not be satisfied but when
   the path is extended it might be.  In particular indicate in
   *LARGE_NON_FSM whether the thread is too large for a non-FSM thread
   but would be OK if we extend the path to cover the loop backedge.

   NAME is the SSA_NAME of the variable we found to have a constant
   value on PATH.  If unknown, SSA_NAME is NULL.

   ?? It seems we should be able to loosen some of the restrictions in
   this function after loop optimizations have run.  */

bool
back_threader_profitability::possibly_profitable_path_p
				  (const vec<basic_block> &m_path, tree name,
				   bool *large_non_fsm)
{
  gcc_checking_assert (!m_path.is_empty ());

  /* We can an empty path here (excluding the DEF block) when the
     statement that makes a conditional generate a compile-time
     constant result is in the same block as the conditional.

     That's not really a jump threading opportunity, but instead is
     simple cprop & simplification.  We could handle it here if we
     wanted by wiring up all the incoming edges.  If we run this
     early in IPA, that might be worth doing.   For now we just
     reject that case.  */
  if (m_path.length () <= 1)
      return false;

  gimple_stmt_iterator gsi;
  loop_p loop = m_path[0]->loop_father;

  // We recompute the following, when we rewrite possibly_profitable_path_p
  // to work incrementally on added BBs we have to unwind them on backtracking
  m_n_insns = 0;
  m_threaded_through_latch = false;
  m_multiway_branch_in_path = false;
  m_contains_hot_bb = false;

  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "Checking profitability of path (backwards): ");

  /* Count the number of instructions on the path: as these instructions
     will have to be duplicated, we will not record the path if there
     are too many instructions on the path.  Also check that all the
     blocks in the path belong to a single loop.  */
  for (unsigned j = 0; j < m_path.length (); j++)
    {
      basic_block bb = m_path[j];

      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, " bb:%i", bb->index);
      /* Remember, blocks in the path are stored in opposite order in
	 the PATH array.  The last entry in the array represents the
	 block with an outgoing edge that we will redirect to the jump
	 threading path.  Thus we don't care how many statements are
	 in that block because it will not be copied or whether or not
	 it ends in a multiway branch.  */
      if (j < m_path.length () - 1)
	{
	  int orig_n_insns = m_n_insns;
	  /* PHIs in the path will create degenerate PHIS in the
	     copied path which will then get propagated away, so
	     looking at just the duplicate path the PHIs would
	     seem unimportant.

	     But those PHIs, because they're assignments to objects
	     typically with lives that exist outside the thread path,
	     will tend to generate PHIs (or at least new PHI arguments)
	     at points where we leave the thread path and rejoin
	     the original blocks.  So we do want to account for them.

	     We ignore virtual PHIs.  We also ignore cases where BB
	     has a single incoming edge.  That's the most common
	     degenerate PHI we'll see here.  Finally we ignore PHIs
	     that are associated with the value we're tracking as
	     that object likely dies.  */
	  if (EDGE_COUNT (bb->succs) > 1 && EDGE_COUNT (bb->preds) > 1)
	    {
	      for (gphi_iterator gsip = gsi_start_phis (bb);
		   !gsi_end_p (gsip);
		   gsi_next (&gsip))
		{
		  gphi *phi = gsip.phi ();
		  tree dst = gimple_phi_result (phi);

		  /* Note that if both NAME and DST are anonymous
		     SSA_NAMEs, then we do not have enough information
		     to consider them associated.  */
		  if (dst != name
		      && name
		      && TREE_CODE (name) == SSA_NAME
		      && (SSA_NAME_VAR (dst) != SSA_NAME_VAR (name)
			  || !SSA_NAME_VAR (dst))
		      && !virtual_operand_p (dst))
		    ++m_n_insns;
		}
	    }

	  if (!m_contains_hot_bb && m_speed_p)
	    m_contains_hot_bb |= optimize_bb_for_speed_p (bb);
	  for (gsi = gsi_after_labels (bb);
	       !gsi_end_p (gsi);
	       gsi_next_nondebug (&gsi))
	    {
	      /* Do not allow OpenACC loop markers and __builtin_constant_p on
		 threading paths.  The latter is disallowed, because an
		 expression might be constant on two threading paths, and
		 become non-constant (i.e.: phi) when they merge.  */
	      gimple *stmt = gsi_stmt (gsi);
	      if (gimple_call_internal_p (stmt, IFN_UNIQUE)
		  || gimple_call_builtin_p (stmt, BUILT_IN_CONSTANT_P))
		{
		  if (dump_file && (dump_flags & TDF_DETAILS))
		    fputc ('\n', dump_file);
		  return false;
		}
	      /* Do not count empty statements and labels.  */
	      if (gimple_code (stmt) != GIMPLE_NOP
		  && !is_gimple_debug (stmt))
		m_n_insns += estimate_num_insns (stmt, &eni_size_weights);
	    }
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file, " (%i insns)", m_n_insns-orig_n_insns);

	  /* We do not look at the block with the threaded branch
	     in this loop.  So if any block with a last statement that
	     is a GIMPLE_SWITCH or GIMPLE_GOTO is seen, then we have a
	     multiway branch on our path.

	     The block in PATH[0] is special, it's the block were we're
	     going to be able to eliminate its branch.  */
	  if (j > 0)
	    {
	      gimple *last = last_stmt (bb);
	      if (last
		  && (gimple_code (last) == GIMPLE_SWITCH
		      || gimple_code (last) == GIMPLE_GOTO))
		m_multiway_branch_in_path = true;
	    }
	}

      /* Note if we thread through the latch, we will want to include
	 the last entry in the array when determining if we thread
	 through the loop latch.  */
      if (loop->latch == bb)
	{
	  m_threaded_through_latch = true;
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file, " (latch)");
	}
    }

  /* We are going to remove the control statement at the end of the
     last block in the threading path.  So don't count it against our
     statement count.  */
  m_n_insns -= m_exit_jump_benefit;

  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "\n  Control statement insns: %i\n"
	     "  Overall: %i insns\n",
	     m_exit_jump_benefit, m_n_insns);

  /* Threading is profitable if the path duplicated is hot but also
     in a case we separate cold path from hot path and permit optimization
     of the hot path later.  Be on the agressive side here. In some testcases,
     as in PR 78407 this leads to noticeable improvements.  */
  if (m_speed_p)
    {
      if (m_n_insns >= param_max_fsm_thread_path_insns)
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file, "  FAIL: Jump-thread path not considered: "
		     "the number of instructions on the path "
		     "exceeds PARAM_MAX_FSM_THREAD_PATH_INSNS.\n");
	  return false;
	}
      edge entry = find_edge (m_path[m_path.length () - 1],
			      m_path[m_path.length () - 2]);
      if (probably_never_executed_edge_p (cfun, entry))
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file, "  FAIL: Jump-thread path not considered: "
		     "path entry is probably never executed.\n");
	  return false;
	}
    }
  else if (m_n_insns > 1)
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "  FAIL: Jump-thread path not considered: "
		 "duplication of %i insns is needed and optimizing for size.\n",
		 m_n_insns);
      return false;
    }

  /* The generic copier used by the backthreader does not re-use an
     existing threading path to reduce code duplication.  So for that
     case, drastically reduce the number of statements we are allowed
     to copy.  We don't know yet whether we will thread through the latch
     so we have to be permissive and continue threading, but indicate
     to the caller the thread, if final, wouldn't be profitable.  */
  if ((!m_threaded_multiway_branch
       || !loop->latch
       || loop->latch->index == EXIT_BLOCK)
      && (m_n_insns * param_fsm_scale_path_stmts
	  >= param_max_jump_thread_duplication_stmts))
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file,
		 "  FAIL: Did not thread around loop and would copy too "
		 "many statements.\n");
      return false;
    }
  *large_non_fsm = (!(m_threaded_through_latch && m_threaded_multiway_branch)
		    && (m_n_insns * param_fsm_scale_path_stmts
			>= param_max_jump_thread_duplication_stmts));

  if (dump_file && (dump_flags & TDF_DETAILS))
    fputc ('\n', dump_file);
  return true;
}

/* Examine jump threading path PATH and return TRUE if it is profitable to
   thread it, otherwise return FALSE.

   The taken edge out of the path is TAKEN_EDGE.

   CREATES_IRREDUCIBLE_LOOP is set to TRUE if threading this path
   would create an irreducible loop.

   ?? It seems we should be able to loosen some of the restrictions in
   this function after loop optimizations have run.  */

bool
back_threader_profitability::profitable_path_p (const vec<basic_block> &m_path,
						edge taken_edge,
						bool *creates_irreducible_loop)
{
  // We can assume that possibly_profitable_path_p holds here

  loop_p loop = m_path[0]->loop_father;

  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "Checking profitability of path (backwards): ");

  /* If this path threaded through the loop latch back into the
     same loop and the destination does not dominate the loop
     latch, then this thread would create an irreducible loop.  */
  *creates_irreducible_loop = false;
  if (m_threaded_through_latch
      && loop == taken_edge->dest->loop_father
      && (determine_bb_domination_status (loop, taken_edge->dest)
	  == DOMST_NONDOMINATING))
    *creates_irreducible_loop = true;

  /* Threading is profitable if the path duplicated is hot but also
     in a case we separate cold path from hot path and permit optimization
     of the hot path later.  Be on the agressive side here. In some testcases,
     as in PR 78407 this leads to noticeable improvements.  */
  if (m_speed_p
      && (optimize_edge_for_speed_p (taken_edge) || m_contains_hot_bb))
    {
      if (probably_never_executed_edge_p (cfun, taken_edge))
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file, "  FAIL: Jump-thread path not considered: "
		     "path leads to probably never executed edge.\n");
	  return false;
	}
    }
  else if (m_n_insns > 1)
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "  FAIL: Jump-thread path not considered: "
		 "duplication of %i insns is needed and optimizing for size.\n",
		 m_n_insns);
      return false;
    }

  /* We avoid creating irreducible inner loops unless we thread through
     a multiway branch, in which case we have deemed it worth losing
     other loop optimizations later.

     We also consider it worth creating an irreducible inner loop if
     the number of copied statement is low relative to the length of
     the path -- in that case there's little the traditional loop
     optimizer would have done anyway, so an irreducible loop is not
     so bad.  */
  if (!m_threaded_multiway_branch
      && *creates_irreducible_loop
      && (m_n_insns * (unsigned) param_fsm_scale_path_stmts
	  > (m_path.length () *
	     (unsigned) param_fsm_scale_path_blocks)))

    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file,
		 "  FAIL: Would create irreducible loop without threading "
		 "multiway branch.\n");
      /* We compute creates_irreducible_loop only late.  */
      return false;
    }

  /* The generic copier used by the backthreader does not re-use an
     existing threading path to reduce code duplication.  So for that
     case, drastically reduce the number of statements we are allowed
     to copy.  */
  if (!(m_threaded_through_latch && m_threaded_multiway_branch)
      && (m_n_insns * param_fsm_scale_path_stmts
	  >= param_max_jump_thread_duplication_stmts))
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file,
		 "  FAIL: Did not thread around loop and would copy too "
		 "many statements.\n");
      return false;
    }

  /* When there is a multi-way branch on the path, then threading can
     explode the CFG due to duplicating the edges for that multi-way
     branch.  So like above, only allow a multi-way branch on the path
     if we actually thread a multi-way branch.  */
  if (!m_threaded_multiway_branch && m_multiway_branch_in_path)
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file,
		 "  FAIL: Thread through multiway branch without threading "
		 "a multiway branch.\n");
      return false;
    }

  /* Threading through an empty latch would cause code to be added to
     the latch.  This could alter the loop form sufficiently to cause
     loop optimizations to fail.  Disable these threads until after
     loop optimizations have run.  */
  if ((m_threaded_through_latch || taken_edge->dest == loop->latch)
      && !(cfun->curr_properties & PROP_loop_opts_done)
      && empty_block_p (loop->latch))
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file,
		 "  FAIL: Thread through latch before loop opts would create "
		 "non-empty latch\n");
      return false;
    }
  if (dump_file && (dump_flags & TDF_DETAILS))
    fputc ('\n', dump_file);
  return true;
}


/* The current path PATH is a vector of blocks forming a jump threading
   path in reverse order.  TAKEN_EDGE is the edge taken from path[0].

   Convert the current path into the form used by register_jump_thread and
   register it.

   Return TRUE if successful or FALSE otherwise.  */

bool
back_threader_registry::register_path (const vec<basic_block> &m_path,
				       edge taken_edge)
{
  vec<jump_thread_edge *> *jump_thread_path = allocate_thread_path ();

  // The generic copier ignores the edge type.  We can build the
  // thread edges with any type.
  for (unsigned int j = 0; j + 1 < m_path.length (); j++)
    {
      basic_block bb1 = m_path[m_path.length () - j - 1];
      basic_block bb2 = m_path[m_path.length () - j - 2];

      edge e = find_edge (bb1, bb2);
      gcc_assert (e);
      push_edge (jump_thread_path, e, EDGE_COPY_SRC_BLOCK);
    }

  push_edge (jump_thread_path, taken_edge, EDGE_NO_COPY_SRC_BLOCK);
  return register_jump_thread (jump_thread_path);
}

// Thread all suitable paths in the current function.
//
// Return TODO_flags.

unsigned int
back_threader::thread_blocks ()
{
  basic_block bb;
  FOR_EACH_BB_FN (bb, m_fun)
    if (EDGE_COUNT (bb->succs) > 1)
      maybe_thread_block (bb);

  bool changed = m_registry.thread_through_all_blocks (true);

  if (m_flags & BT_SPEED)
    return changed ? TODO_cleanup_cfg : 0;

  return false;
}

namespace {

const pass_data pass_data_early_thread_jumps =
{
  GIMPLE_PASS,
  "ethread",
  OPTGROUP_NONE,
  TV_TREE_SSA_THREAD_JUMPS,
  ( PROP_cfg | PROP_ssa ),
  0,
  0,
  0,
  ( TODO_cleanup_cfg | TODO_update_ssa ),
};

const pass_data pass_data_thread_jumps =
{
  GIMPLE_PASS,
  "thread",
  OPTGROUP_NONE,
  TV_TREE_SSA_THREAD_JUMPS,
  ( PROP_cfg | PROP_ssa ),
  0,
  0,
  0,
  TODO_update_ssa,
};

const pass_data pass_data_thread_jumps_full =
{
  GIMPLE_PASS,
  "threadfull",
  OPTGROUP_NONE,
  TV_TREE_SSA_THREAD_JUMPS,
  ( PROP_cfg | PROP_ssa ),
  0,
  0,
  0,
  TODO_update_ssa,
};

// Early jump threading pass optimizing for size.
class pass_early_thread_jumps : public gimple_opt_pass
{
public:
  pass_early_thread_jumps (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_early_thread_jumps, ctxt)
  {}

  opt_pass * clone () override
  {
    return new pass_early_thread_jumps (m_ctxt);
  }
  void set_pass_param (unsigned int, bool param) override
  {
    m_first = param;
  }
  bool gate (function *) override
  {
    return flag_thread_jumps;
  }
  unsigned int execute (function *fun) override
  {
    back_threader threader (fun, BT_NONE, m_first);
    return threader.thread_blocks ();
  }
private:
  bool m_first;
};

// Jump threading pass without resolving of unknown SSAs.
class pass_thread_jumps : public gimple_opt_pass
{
public:
  pass_thread_jumps (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_thread_jumps, ctxt)
  {}
  opt_pass * clone (void) override
  {
    return new pass_thread_jumps (m_ctxt);
  }
  void set_pass_param (unsigned int, bool param) override
  {
    m_first = param;
  }
  bool gate (function *) override
  {
    return flag_thread_jumps && flag_expensive_optimizations;
  }
  unsigned int execute (function *fun) override
  {
    back_threader threader (fun, BT_SPEED, m_first);
    return threader.thread_blocks ();
  }
private:
  bool m_first;
};

// Jump threading pass that fully resolves unknown SSAs.
class pass_thread_jumps_full : public gimple_opt_pass
{
public:
  pass_thread_jumps_full (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_thread_jumps_full, ctxt)
  {}
  opt_pass * clone (void) override
  {
    return new pass_thread_jumps_full (m_ctxt);
  }
  void set_pass_param (unsigned int, bool param) override
  {
    m_first = param;
  }
  bool gate (function *) override
  {
    return flag_thread_jumps && flag_expensive_optimizations;
  }
  unsigned int execute (function *fun) override
  {
    back_threader threader (fun, BT_SPEED | BT_RESOLVE, m_first);
    return threader.thread_blocks ();
  }
private:
  bool m_first;
};

} // namespace {

gimple_opt_pass *
make_pass_thread_jumps (gcc::context *ctxt)
{
  return new pass_thread_jumps (ctxt);
}

gimple_opt_pass *
make_pass_thread_jumps_full (gcc::context *ctxt)
{
  return new pass_thread_jumps_full (ctxt);
}

gimple_opt_pass *
make_pass_early_thread_jumps (gcc::context *ctxt)
{
  return new pass_early_thread_jumps (ctxt);
}
