/* SSA Jump Threading
   Copyright (C) 2005-2025 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> &, 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;
  // 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 = range_true ();
  int_range<2> false_range = range_false ();

  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)
{
  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, &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
	   && !m_visited_bbs.add (bb))
    {
      // 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);
      m_visited_bbs.remove (bb);
    }
  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 ();
}

// 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 = *gsi_last_bb (bb);
  if (!stmt)
    return;

  enum gimple_code code = gimple_code (stmt);
  if (code != GIMPLE_SWITCH
      && code != GIMPLE_COND)
    return;

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

  // We compute imports of the path during discovery starting
  // just with names used in the conditional.
  bitmap_clear (m_imports);
  ssa_op_iter iter;
  tree name;
  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.

   ?? 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,
				   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;
	  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 = *gsi_last_bb (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 after
     loop optimizations if the number of copied statement is low.  */
  if (!m_threaded_multiway_branch
      && *creates_irreducible_loop
      && (!(cfun->curr_properties & PROP_loop_opts_done)
	  || (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: Would create irreducible loop early 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);
}
