/* CRC optimization.
   Copyright (C) 2022-2026 Free Software Foundation, Inc.
   Contributed by Mariam Arutunian <mariamarutunian@gmail.com>

This file is part of GCC.

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

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

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

/* This pass performs CRC optimization.  */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "gimple.h"
#include "tree-pass.h"
#include "ssa.h"
#include "gimple-iterator.h"
#include "tree-cfg.h"
#include "cfgloop.h"
#include "tree-scalar-evolution.h"
#include "crc-verification.h"
#include "internal-fn.h"
#include "predict.h"

class crc_optimization {
 private:
  /* Record of statements already seen.  */
  bitmap m_visited_stmts;

  /* Input CRC of the loop.  */
  tree m_crc_arg;

  /* Input data of the loop.  */
  tree m_data_arg;

  /* The statement doing shift 1 operation before/after xor operation.  */
  gimple *m_shift_stmt;

  /* Phi statement from the head of the loop for CRC.  */
  gphi *m_phi_for_crc;

  /* Phi statement for the data from the head of the loop if exists,
     otherwise - nullptr.  */
  gphi *m_phi_for_data;

  /* The loop, which probably calculates CRC.  */
  class loop *m_crc_loop;

  /* Polynomial used in CRC calculation.  */
  unsigned HOST_WIDE_INT m_polynomial;

  /* Depending on the value of M_IS_BIT_FORWARD, may be forward or reversed CRC.
     If M_IS_BIT_FORWARD, then it is bit-forward implementation,
     otherwise bit-reversed.  */
  bool m_is_bit_forward;

  /* Sets initial values for CRC analyses.  */
  void set_initial_values ();

  /* This is the main function that checks whether the given LOOP
     calculates CRC and extracts details of the CRC calculation.

     The main idea is to find the innermost loop with 8, 16, 24, 32, 64
     iterations and xor instruction (xor is the key operation for naive CRC
     calculation). Then, checks that the variable is shifted by one before/after
     being used in xor.
     Xor must be done under the condition of MSB/LSB being 1.  */
  bool loop_may_calculate_crc (class loop *loop);

  /* Symbolically executes the loop and checks that LFSR and resulting states
     match.
     Returns true if it is verified that the loop calculates CRC.
     Otherwise, return false.
     OUTPUT_CRC is the phi statement which will hold the calculated CRC value
     after the loop exit.  */
  bool loop_calculates_crc (gphi *output_crc,
			    std::pair<tree, value *> calc_polynom);

  /* Returns true if there is only two conditional blocks in the loop
     (one may be for the CRC bit check and the other for the loop counter).
     This may filter out some real CRCs, where more than one condition
     is checked for the CRC calculation.  */
  static bool loop_contains_two_conditional_bb (basic_block *loop_bbs,
						unsigned loop_num_nodes);

  /* Checks the FUNC_LOOP loop's iteration number.
     The loop for CRC calculation may do 8, 16, 24, 32, 64 iterations.  */
  bool satisfies_crc_loop_iteration_count (class loop *func_loop);

  /* This function checks if the XOR_STMT is used for CRC calculation.
     It verifies the presence of a shift operation in the CRC_FUN function
     inside the CRC loop.  It examines operands of XOR, its dependencies, the
     relative position of the shift operation, and the existence of a shift
     operation in the opposite branch of conditional statements.  It also
     checks if XOR is performed when MSB/LSB is one.
     If these conditions are met, the XOR operation may be part of a CRC
     calculation.  The function returns true if these conditions are fulfilled,
     otherwise, it returns false.  */
  bool xor_calculates_crc (function *crc_fun, const gimple *xor_stmt);

  /* Returns true if we can get definition of the VARIABLE, and the definition
     it's not outside the loop.  Otherwise, returns false.  */
  bool passes_checks_for_def_chain (tree variable);

  /* This function goes up through the def-use chains of the parameter NAME.
     Gathers all the statements within the loop,
     from which the variable depends on and adds to the USE_DEFS.
     Returns false, if there is a statement that may not exist in the CRC
     loop.  Otherwise, returns true.  */
  bool set_defs (tree name, auto_vec<gimple *>& use_defs,
		 bool keep_only_header_phis);

  /* Set M_PHI_FOR_CRC and M_PHI_FOR_DATA fields.
     Returns false if there are more than two (as in CRC calculation only CRC's
     and data's phi may exist) or no phi statements in STMTS (at least there
     must be CRC's phi).
     Otherwise, returns true.  */
  bool set_crc_and_data_phi (auto_vec<gimple *>& stmts);

  /*  Returns true if the variable checked in the condition depends on possible
      CRC value.  Otherwise, returns false.  */
  bool cond_depends_on_crc (auto_vec<gimple *>& stmts);


  /* Checks that the condition is for checking CRC.
     Returns true if xor is done under the condition of MSB/LSB being 1, and
     the condition's variable and xor-ed variable depend on the same variable.
     Otherwise, returns false.
     XOR_BB is the basic block, where the xor operation is done.
     PRED_BB is the predecessor basic block of the XOR_BB, it is assumed that
     the last stmt of PRED_BB checks the condition under which xor is done.  */
  bool crc_cond (basic_block pred_bb, basic_block xor_bb);

  /* Returns true if xor is done in case the MSB/LSB is 1.
     Otherwise, returns false.
     In CRC calculation algorithms CRC is xor-ed with the polynomial only
     if MSB/LSB is 1.

     PRED_BB is the block containing the condition for the xor.
     XOR_BB is the one of the successor blocks of PRED_BB, it is assumed that
     CRC is xor-ed with the polynomial in XOR_BB.
     COND is the condition, which is checked to satisfy the CRC condition.  */
  bool is_crc_satisfiable_cond (basic_block pred_bb, basic_block xor_bb,
				gcond *cond);

  /* Checks that the variable used in the condition COND is the assumed CRC
     (or depends on the assumed CRC).
     Also sets data member m_phi_for_data if it isn't set and exists.  */
  bool is_crc_checked (gcond *cond);

  /* Returns true if condition COND checks MSB/LSB bit is 1.
     Otherwise, return false.  */
  static bool cond_true_is_checked_for_bit_one (const gcond *cond);

  /* Returns opposite block of the XOR_BB from PRED_BB's dest blocks.  */
  static basic_block get_xor_bb_opposite (basic_block pred_bb,
					  basic_block xor_bb);

  /* Checks whether the pair of xor's shift exists in the opposite
     basic block (OPPOSITE_BB).
     If there is a shift and xor in the same block,
     then in the opposite block must be another shift.  */
  bool exists_shift_for_opp_xor_shift (basic_block opposite_bb);

  /* Follow def-use chains of XORED_CRC and return the statement where
     XORED_CRC is shifted by one bit position.  Only PHI statements are
     allowed between XORED_CRC and the shift in the def-use chain.

   If no such statement is found, return NULL.  */
  gimple *find_shift_after_xor (tree xored_crc);

  /* Returns the statement which does shift 1 operation.
     If there is no such statement, returns nullptr.
     STMTS - are the statements within the loop before xor operation on
     which possible CRC variable depends.  */
  gimple *find_shift_before_xor (const auto_vec <gimple *> &stmts);

  /* Returns true if ASSIGN_STMT does shift with 1.
     Otherwise, returns false.  */
  bool can_be_crc_shift (gimple *assign_stmt);

  /* Returns true if the operation done in ASSIGN_STMT can occur during CRC
     calculation.  Otherwise, returns false.  */
  bool can_not_be_crc_stmt (gimple *assign_stmt);

  /* Returns true if the statement with STMT_CODE may occur in CRC calculation.
     Otherwise, returns false.  */
  static bool is_acceptable_stmt_code (const tree_code &stmt_code);

  /* Prints extracted details of CRC calculation.  */
  void dump_crc_information ();

  /* Returns true if OUTPUT_CRC's result is the input of m_phi_for_crc.
     Otherwise, returns false.  */
  bool is_output_crc (gphi *output_crc);

  /* Swaps m_phi_for_crc and m_phi_for_data if they are mixed.  */
  void swap_crc_and_data_if_needed (gphi *output_crc);

  /* Validates CRC and data arguments and
   sets them for potential CRC loop replacement.

   The function extracts the CRC and data arguments from PHI nodes and
   performs several checks to ensure that the CRC and data are suitable for
   replacing the CRC loop with a more efficient implementation.

  Returns true if the arguments are valid and the loop replacement is possible,
  false otherwise.  */
  bool validate_crc_and_data ();

  /* Convert polynomial to unsigned HOST_WIDE_INT.  */
  void construct_constant_polynomial (value *polynomial);

  /* Returns phi statement which may hold the calculated CRC.  */
  gphi *get_output_phi ();

  /* Attempts to optimize a CRC calculation calculated by LOOP by replacing it
     with a call to an internal function (IFN_CRC or IFN_CRC_REV).
     Returns true if replacement succeeded, otherwise false.  */
  bool optimize_crc_loop (class loop *loop, gphi *output_crc);

 public:
  crc_optimization () : m_visited_stmts (BITMAP_ALLOC (NULL)),
			m_crc_loop (nullptr), m_polynomial (0)
  {
    set_initial_values ();
  }
  ~crc_optimization ()
  {
    BITMAP_FREE (m_visited_stmts);
  }
  unsigned int execute (function *fun);
};

/* Prints extracted details of CRC calculation.  */

void
crc_optimization::dump_crc_information ()
{
  if (dump_file)
    {
      fprintf (dump_file,
	       "Loop iteration number is " HOST_WIDE_INT_PRINT_UNSIGNED ".\n",
	       tree_to_uhwi (m_crc_loop->nb_iterations));
      if (m_is_bit_forward)
	fprintf (dump_file, "Bit forward.\n");
      else
	fprintf (dump_file, "Bit reversed.\n");
    }
}

/* Goes down by def-use chain (within the CRC loop) and returns the statement
   where variable (dependent on xor-ed variable) is shifted with 1.
   Between xor and shift operations only phi statements are allowed.
   Otherwise, returns nullptr.  */

gimple *
crc_optimization::find_shift_after_xor (tree xored_crc)
{
  imm_use_iterator imm_iter;
  use_operand_p use_p;

  gcc_assert (TREE_CODE (xored_crc) == SSA_NAME);

  unsigned v = SSA_NAME_VERSION (xored_crc);
  if (bitmap_bit_p (m_visited_stmts, v))
    return nullptr;
  bitmap_set_bit (m_visited_stmts, v);

  /* Iterate through the immediate uses of the XORED_CRC.
     If there is a shift return true,
     if before shift there is other instruction (besides phi) return false.  */
  FOR_EACH_IMM_USE_FAST (use_p, imm_iter, xored_crc)
    {
      gimple *stmt = USE_STMT (use_p);
      // Consider only statements within the loop
      if (!flow_bb_inside_loop_p (m_crc_loop, gimple_bb (stmt)))
	continue;

      /* If encountered phi statement, check immediate use of its result.
	 Otherwise, if encountered assign statement, check whether it does shift
	 (some other operations are allowed to be between shift and xor).  */
      if (gimple_code (stmt) == GIMPLE_PHI)
	{
	  /* Don't continue searching if encountered the loop's beginning.  */
	  if (bb_loop_header_p (gimple_bb (stmt)))
	    continue;

	  return find_shift_after_xor (gimple_phi_result (stmt));
	}
      else if (is_gimple_assign (stmt))
	{
	  /* Check that stmt does shift by 1.
	     There are no other statements between
	     xor and shift, in CRC cases we detect.  */
	  if (can_be_crc_shift (stmt))
	    return stmt;
	  return nullptr;
	}
      else if (!is_gimple_debug (stmt))
	return  nullptr;
    }
    return nullptr;
}

/* Returns opposite block of the XOR_BB from PRED_BB's dest blocks.  */

basic_block
crc_optimization::get_xor_bb_opposite (basic_block pred_bb, basic_block xor_bb)
{
  /* Check that the predecessor block has exactly two successors.  */
  if (EDGE_COUNT (pred_bb->succs) != 2)
    return nullptr;

  edge e0 = EDGE_SUCC (pred_bb, 0);
  edge e1 = EDGE_SUCC (pred_bb, 1);

  /* Ensure neither outgoing edge is marked as complex.  */
  if ((e0->flags & EDGE_COMPLEX)
      || (e1->flags & EDGE_COMPLEX))
    return nullptr;

  /* Check that one of the successors is indeed XOR_BB.  */
  gcc_assert ((e0->dest == xor_bb)
	      || (e1->dest == xor_bb));

  /* Return the opposite block of XOR_BB.  */
  if (EDGE_SUCC (pred_bb, 0)->dest != xor_bb)
    return e0->dest;
  return e1->dest;
}

/* Checks whether the pair of xor's shift exists in the opposite
   basic block (OPPOSITE_BB).
   If there is a shift and xor in the same block,
   then in the opposite block must be another shift.  */

bool
crc_optimization::exists_shift_for_opp_xor_shift (basic_block opposite_bb)
{
  if (!opposite_bb)
    return false;

  /* Walk through the instructions of given basic block.  */
  for (gimple_stmt_iterator bsi = gsi_start_nondebug_bb (opposite_bb);
       !gsi_end_p (bsi); gsi_next_nondebug (&bsi))
    {
      gimple *stmt = gsi_stmt (bsi);
      /* Find assignment statement with shift operation.
	 Check that shift's direction is same with the shift done
	 on the path with xor, and it is a shift by one.  */
      if (is_gimple_assign (stmt))
	{
	  if ((gimple_assign_rhs_code (stmt)
	       == gimple_assign_rhs_code (m_shift_stmt))
	      && integer_onep (gimple_assign_rhs2 (stmt)))
	    return true;
	}
    }
  /* If there is no shift, return false.  */
  return false;
}

/* Returns true if condition COND checks MSB/LSB bit is 1.
   Otherwise, return false.  */

bool
crc_optimization::cond_true_is_checked_for_bit_one (const gcond *cond)
{
  if (!cond)
    return false;

  tree rhs = gimple_cond_rhs (cond);
  enum tree_code code = gimple_cond_code (cond);

  /* If the condition is something == 1 -> return true.  */
  if (code == EQ_EXPR && integer_onep (rhs))
    return true;

  /* If the condition is something != 0  or something < 0 -> return true.  */
  if ((code == NE_EXPR || code == LT_EXPR)
       && integer_zerop (rhs))
    return true;

  return false;
}

/* Returns true if xor is done in case the MSB/LSB is 1.
   Otherwise, returns false.
   In CRC calculation algorithms CRC is xor-ed with the polynomial only
   if MSB/LSB is 1.

   PRED_BB is the block containing the condition for the xor.
   XOR_BB is the one of the successor blocks of PRED_BB, it is assumed that CRC
   is xor-ed with the polynomial in XOR_BB.
   COND is the condition, which is checked to satisfy the CRC condition.  */

bool
crc_optimization::is_crc_satisfiable_cond (basic_block pred_bb,
					   basic_block xor_bb,
					   gcond *cond)
{
  edge true_edge;
  edge false_edge;
  extract_true_false_edges_from_block (pred_bb, &true_edge, &false_edge);
  bool cond_is_checked_for_bit_one = cond_true_is_checked_for_bit_one (cond);
  /* Check that xor is done in case the MSB/LSB is 1.  */
  if (cond_is_checked_for_bit_one && true_edge->dest == xor_bb)
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "Xor is done on true branch.\n");
    }
  else if (!cond_is_checked_for_bit_one && false_edge->dest == xor_bb)
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "Xor is done on false branch.\n");
    }
  else
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file,
		 "Xor is done if MSB/LSB is not one, not CRC.\n");
      return false;
    }
  return true;
}

/* Checks that the variable used in the condition COND is the assumed CRC
  (or depends on the assumed CRC).
  Also sets data member m_phi_for_data if it isn't set and exists.  */

bool
crc_optimization::is_crc_checked (gcond *cond)
{
  tree lhs = gimple_cond_lhs (cond);

  /* As conditions are in canonical form, only left part must be an
    SSA_NAME.  */
  if (TREE_CODE (lhs) == SSA_NAME)
    {
      /* Return whether there is a dependence between if condition's variable
	 and xor-ed variable.  Also set phi statement of data if it is not
	 determined earlier and is used in the loop.  */
      auto_vec<gimple *> cond_dep_stmts (m_crc_loop->num_nodes);
      bool set_defs_succeeded = set_defs (lhs, cond_dep_stmts, true);
      bitmap_clear (m_visited_stmts);
      if (!set_defs_succeeded)
	return false;
      return cond_depends_on_crc (cond_dep_stmts);
    }

  /* Return false if there is no dependence between if condition's variable
     and xor-ed variable.  */
  return false;
}

/* Checks that the condition is for checking CRC.
   Returns true if xor is done under the condition of MSB/LSB being 1, and
   the condition's variable and xor-ed variable depend on the same variable.
   Otherwise, returns false.
   XOR_BB is the basic block, where the xor operation is done.
   PRED_BB is the predecessor basic block of the XOR_BB, it is assumed that
   the last stmt of PRED_BB checks the condition under which xor is done.  */

bool
crc_optimization::crc_cond (basic_block pred_bb, basic_block xor_bb)
{
  /* Check whether PRED_BB contains condition.  We will consider only those
     cases when xor is done immediately under the condition.  */
  gcond *cond = safe_dyn_cast<gcond *> (gsi_stmt (gsi_last_bb (pred_bb)));
  if (!cond)
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "No condition.\n");
      return false;
    }

  /* Check that xor is done in case the MSB/LSB is 1.  */
  if (!is_crc_satisfiable_cond (pred_bb, xor_bb, cond))
    return false;

  /* Check that CRC's MSB/LSB is checked in the condition.
     Set data member if not set and exists.  */
  if (!is_crc_checked (cond))
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "The condition is not related to the CRC check.\n");
      return false;
    }
  return true;
}

/* Returns true if the statement with STMT_CODE may occur in CRC calculation.
   Otherwise, returns false.  */

bool
crc_optimization::is_acceptable_stmt_code (const tree_code &stmt_code)
{
  return (stmt_code == BIT_IOR_EXPR)
	 || (stmt_code == BIT_AND_EXPR)
	 || (stmt_code == BIT_XOR_EXPR)
	 || (stmt_code == MINUS_EXPR)
	 || (stmt_code == PLUS_EXPR)
	 || (stmt_code == RSHIFT_EXPR)
	 || (stmt_code == LSHIFT_EXPR)
	 || (TREE_CODE_CLASS (stmt_code) == tcc_unary);
}

/* Returns true if ASSIGN_STMT does shift with 1.  Otherwise, returns false.  */

bool
crc_optimization::can_be_crc_shift (gimple *assign_stmt)
{
  tree_code stmt_code = gimple_assign_rhs_code (assign_stmt);
  if (stmt_code == LSHIFT_EXPR || stmt_code == RSHIFT_EXPR)
    {
      m_is_bit_forward = (stmt_code == LSHIFT_EXPR);
      /* Check that shift one is done, keep shift statement.  */
      if (integer_onep (gimple_assign_rhs2 (assign_stmt)))
	{
	  if (m_shift_stmt)
	    {
	      if (dump_file && (dump_flags & TDF_DETAILS))
		fprintf (dump_file,
			 "Already there is one shift.\n");
	      return false;
	    }
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file,
		     "Found <<1 or >>1.\n");
	  return true;
	}
      /* This filters out cases, when xor-ed variable is shifted by values
	 other than 1.  */
    }
    return false;
}

/* Returns true if the operation done in ASSIGN_STMT can occur during CRC
   calculation.  Otherwise, returns false.  */

bool
crc_optimization::can_not_be_crc_stmt (gimple *assign_stmt)
{
  tree_code stmt_code = gimple_assign_rhs_code (assign_stmt);
  if (!is_acceptable_stmt_code (stmt_code))
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file,
		 "\nStmt with the following operation "
		 "code %s between xor and shift, "
		 "may not be CRC.\n", get_tree_code_name (stmt_code));

      return true;
    }
  return false;
}

/* Returns true if we can get definition of the VARIABLE, and the definition
   is not outside the loop.  Otherwise, returns false.  */

bool
crc_optimization::passes_checks_for_def_chain (tree variable)
{
  if (!(variable && TREE_CODE (variable) == SSA_NAME))
    return false;

  /* No definition chain for default defs.  */
  if (SSA_NAME_IS_DEFAULT_DEF (variable))
    return false;

  gimple *stmt = SSA_NAME_DEF_STMT (variable);

  if (!stmt)
    return false;

  /* Don't go outside the loop.  */
  if (!flow_bb_inside_loop_p (m_crc_loop, gimple_bb (stmt)))
    return false;

  return true;
}

/* This function goes up through the def-use chains of the parameter NAME.
   Gathers all the statements within the loop,
   from which the variable depends on and adds to the USE_DEFS.
   Returns false, if there is a statement that may not exist in the CRC
   loop.  Otherwise, returns true.  */

bool
crc_optimization::set_defs (tree name, auto_vec<gimple *> &use_defs,
			    bool keep_only_header_phis = false)
{
  if (!passes_checks_for_def_chain (name))
    return true;

  /* Don't consider already visited names.  */
  unsigned v = SSA_NAME_VERSION (name);
  if (bitmap_bit_p (m_visited_stmts, v))
    return true;
  bitmap_set_bit (m_visited_stmts, v);

  /* In CRC implementations with constant polynomial maximum 12 use_def
     statements may occur.  This limit is based on an analysis of various CRC
     implementations as well as theoretical possibilities.
     TODO: Find a better solution.  */
  if (use_defs.length () > 12)
    return false;

  gimple *stmt = SSA_NAME_DEF_STMT (name);

  /* If it's not specified to keep only header phi's,
     then keep all statements.  */
  if (!keep_only_header_phis)
    use_defs.safe_push (stmt);

  /* If it is an assignment statement,
     get and check def-use chain for the first and second operands.  */
  if (is_a<gassign *> (stmt))
    {
      if (can_not_be_crc_stmt (stmt))
	return false;

      tree ssa1 = gimple_assign_rhs1 (stmt);
      tree ssa2 = gimple_assign_rhs2 (stmt);
      if (!set_defs (ssa1, use_defs, keep_only_header_phis))
	return false;
      if (!set_defs (ssa2, use_defs, keep_only_header_phis))
	return false;
      return true;
    }
  /* If it's a phi statement, not declared in loop's header,
     get and check def-use chain for its values.  For the one declared in loop's
     header just return true and keep it, if keep_only_header_phis is true.  */
  else if (is_a<gphi *> (stmt))
    {
      if (bb_loop_header_p (gimple_bb (stmt)))
	{
	  /* If it's specified to keep only header phi's, keep it.  */
	  if (keep_only_header_phis)
	    use_defs.safe_push (stmt);
	}
      else
	{
	  for (unsigned i = 0; i < gimple_phi_num_args (stmt); i++)
	    {
	      tree val = gimple_phi_arg_def (stmt, i);
	      if (!set_defs (val, use_defs, keep_only_header_phis))
		return false;
	    }
	}
      return true;
    }

  /* Return false for other than assigment and phi statement.  */
  return false;
}

/* Returns the statement which does shift 1 operation.
   If there is no such statement, returns nullptr.
   STMTS - are the statements within the loop before xor operation on
   which possible CRC variable depends.  */

gimple *
crc_optimization::find_shift_before_xor (const auto_vec<gimple *> &stmts)
{
  for (auto stmt_it = stmts.begin (); stmt_it != stmts.end (); stmt_it++)
    {
      /* If it is an assignment statement, check that is does shift 1.  */
      if (is_a<gassign *> (*stmt_it))
	{
	  if (can_be_crc_shift (*stmt_it))
	    return *stmt_it;
	}
    }
  return nullptr;
}

/* This function sets M_PHI_FOR_CRC and M_PHI_FOR_DATA fields.
   At this step phi nodes for CRC and data may be mixed in places.
   It is fixed later with the "swap_crc_and_data_if_needed" function.
   The function returns false if there are more than two (as in CRC calculation
   only CRC's and data's phi may exist) or no phi statements in STMTS (at least
   there must be CRC's phi).
   Otherwise, returns true.  */

bool
crc_optimization::set_crc_and_data_phi (auto_vec<gimple *> &stmts)
{
  for (auto stmt_it = stmts.begin (); stmt_it != stmts.end (); stmt_it++)
    {
      if (is_a<gphi *> (*stmt_it) && bb_loop_header_p (gimple_bb (*stmt_it)))
	{
	  if (!m_phi_for_crc)
	    m_phi_for_crc = as_a<gphi *> (*stmt_it);
	  else if (!m_phi_for_data)
	    m_phi_for_data = as_a<gphi *> (*stmt_it);
	  else
	    {
	      if (dump_file && (dump_flags & TDF_DETAILS))
		fprintf (dump_file, "Xor-ed variable depends on more than 2 "
				    "phis.\n");
	      return false;
	    }
	}
    }
  return m_phi_for_crc;
}

/*  Returns true if the variable checked in the condition depends on possible
    CRC value.  Otherwise, returns false.  */

bool
crc_optimization::cond_depends_on_crc (auto_vec<gimple *>& stmts)
{
  bool con_depends_on_crc = false;

  /* The condition may depend maximum on data and CRC phi's.  */
  if (stmts.length () > 2)
    return false;

  for (auto stmt_it = stmts.begin (); stmt_it != stmts.end (); stmt_it++)
    {
      if (is_a<gphi *> (*stmt_it) && bb_loop_header_p (gimple_bb (*stmt_it)))
	{
	  /* Check whether variable checked in the condition depends on
	     M_PHI_FOR_CRC.
	     Here don't stop the check, to set data if needed.  */
	  if (m_phi_for_crc == (*stmt_it))
	    con_depends_on_crc = true;
	  else if (m_phi_for_data && m_phi_for_data == (*stmt_it))
	    return true;
	  /* If M_PHI_FOR_DATA isn't determined, the phi statement maybe for the
	     data.  Just set it.  */
	  else if (!m_phi_for_data)
	    m_phi_for_data = as_a<gphi *> (*stmt_it);
	}
    }
  return con_depends_on_crc;
}

/* Sets initial values for the CRC analysis.
   This function is used multiple times during the analyses.  */

void
crc_optimization::set_initial_values ()
{
  m_crc_arg = nullptr;
  m_data_arg = nullptr;
  m_shift_stmt = nullptr;
  m_phi_for_crc = nullptr;
  m_phi_for_data = nullptr;
  m_is_bit_forward = false;
}

/* This function checks if the XOR_STMT is used for CRC calculation.
   It verifies the presence of a shift operation in the CRC_FUN function inside
   the CRC loop.  It examines operands of XOR, its dependencies, the relative
   position of the shift operation, and the existence of a shift operation in
   the opposite branch of conditional statements.  It also checks if XOR is
   performed when MSB/LSB is one.
   If these conditions are met, the XOR operation may be part of a CRC
   calculation.  The function returns true if these conditions are fulfilled,
   otherwise, it returns false.  */

bool
crc_optimization::xor_calculates_crc (function *crc_fun,
				      const gimple *xor_stmt)
{
  tree crc_var = gimple_assign_lhs (xor_stmt);
  set_initial_values ();
  tree ssa1 = gimple_assign_rhs1 (xor_stmt);
  tree ssa2 = gimple_assign_rhs2 (xor_stmt);
  if (TREE_CODE (ssa2) != INTEGER_CST)
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "Second operand of the "
			    "xor statement isn't an integer constant.\n");
      return false;
    }

  /* Get the statements within the loop on which xor-ed variable depends.  */
  auto_vec<gimple *> xor_dep_stmts (m_crc_loop->num_nodes);
  bool set_defs_succeeded = set_defs (ssa1, xor_dep_stmts);
  bitmap_clear (m_visited_stmts);
  if (!set_defs_succeeded)
    {
      xor_dep_stmts.release ();
      return false;
    }

  m_shift_stmt = find_shift_before_xor (xor_dep_stmts);

  if (!set_crc_and_data_phi (xor_dep_stmts))
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "Xor isn't used for CRC calculation.\n");
      return false;
    }

  /* Check the case when shift is done after xor.  */
  if (!m_shift_stmt)
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "No shift before xor, trying to find after xor.\n");

      m_shift_stmt = find_shift_after_xor (crc_var);
      bitmap_clear (m_visited_stmts);
      if (!m_shift_stmt)
	return false;
    }

  /* Get the basic block where xor operation is done.  */
  basic_block xor_bb = gimple_bb (xor_stmt);

  /* Get the predecessor basic block of xor's block.  */
  if (!single_pred_p (xor_bb))
    return false;
  basic_block block_of_condition = single_pred (xor_bb);


  /* If the found shift operation is in the same block as the xor operation,
     verify whether another shift exists in the opposite branch of the
     conditional statements.  */
  if (m_shift_stmt && gimple_bb (m_shift_stmt) == xor_bb)
    {
      basic_block opposite_block = get_xor_bb_opposite (block_of_condition,
							xor_bb);
      if (!exists_shift_for_opp_xor_shift (opposite_block))
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file,
		     "Opposite block doesn't contain shift's pair.\n");
	  return false;
	}
    }

  /* Check that xor is done if MSB/LSB is one.
     If all checks succeed, then it may be a CRC.  */
  if (crc_cond (block_of_condition, xor_bb))
    {
      if (dump_file)
	fprintf (dump_file,
		 "\n%s function maybe contains CRC calculation.\n",
		 function_name (crc_fun));
      return true;
    }

  return false;
}

/* Returns true if there is only two conditional blocks in the loop,
   one may be for the CRC bit check and the other for the loop counter.
   This may filter out some real CRCs, where more than one condition
   is checked for the CRC calculation and branch-less CRCs.  */

bool
crc_optimization::loop_contains_two_conditional_bb (basic_block *loop_bbs,
						    unsigned loop_num_nodes)
{
  unsigned conditional_bb_count = 0;
  /* Iterate through the loop until the conditional branches count
     is below 3.  */
  for (unsigned i = 0; i < loop_num_nodes && conditional_bb_count <= 2; i++)
    {
      basic_block bb = loop_bbs[i];
      if (!single_succ_p (bb))
	conditional_bb_count++;
    }
  return conditional_bb_count == 2;
}

/* Checks the FUNC_LOOP loop's iteration number.
   The loop for CRC calculation may do 8, 16, 24, 32, 64 iterations.  */

bool
crc_optimization::satisfies_crc_loop_iteration_count (class loop *func_loop)
{
  /* Calculate the number of times the latch of the loop is executed.
     The function sets NB_ITERATIONS field of the loop.  */
  number_of_latch_executions (func_loop);
  tree n_inters = func_loop->nb_iterations;
  if (n_inters == NULL_TREE || n_inters == chrec_dont_know)
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file,
		 "Loop iteration number is chrec_dont_know.\n");
      return false;

    }
  else if (tree_fits_uhwi_p (n_inters))
    {
      unsigned HOST_WIDE_INT
      loop_iteration_number = tree_to_uhwi (n_inters);
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "Loop iteration number is "
		 HOST_WIDE_INT_PRINT_UNSIGNED ".\n", loop_iteration_number);

      if ((loop_iteration_number == 7 || loop_iteration_number == 15
	   || loop_iteration_number == 23 || loop_iteration_number == 31
	   || loop_iteration_number == 63))
	return true;
    }
  if (stderr && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "Loop iteration number isn't a constant.\n");
  return false;
}

/* This is the main function that checks whether the given LOOP
   calculates CRC and extracts details of the CRC calculation.

   The main idea is to find the innermost loop with 8, 16, 24, 32, 64
   iterations and xor instruction (xor is the key operation for naive CRC
   calculation). Then, checks that the variable is shifted by one before/after
   being used in xor.
   Xor must be done under the condition of MSB/LSB being 1.  */

bool
crc_optimization::loop_may_calculate_crc (class loop *loop)
{
  /* Only examine innermost loops.  */
  if (!loop || loop->inner)
    return false;

  if (!satisfies_crc_loop_iteration_count (loop))
    return false;

  m_crc_loop = loop;
  basic_block *loop_bbs = get_loop_body_in_dom_order (m_crc_loop);

  /* Filter out the cases, which don't have exactly two conditions in the loop.
     One for the CRC bit check, the other for the loop counter.  */
  if (!loop_contains_two_conditional_bb (loop_bbs, m_crc_loop->num_nodes))
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file,
		 "The number of conditional "
		 "branches in the loop isn't 2.\n");
      free (loop_bbs);
      return false;
    }

  unsigned short checked_xor_count = 0;
  /* Walk bbs of the loop.  */
  for (unsigned int i = 0; i < m_crc_loop->num_nodes; i++)
    {
      basic_block bb = loop_bbs[i];
      /* Walk instructions of the bb.  */
      for (gimple_stmt_iterator bsi = gsi_start_nondebug_bb (bb);
	   !gsi_end_p (bsi); gsi_next_nondebug (&bsi))
	{
	  gimple *stmt = gsi_stmt (bsi);
	  /* If there is an xor instruction,
	     check that it is calculating CRC.  */
	  if (is_gimple_assign (stmt)
	      && gimple_assign_rhs_code (stmt) == BIT_XOR_EXPR)
	    {
	      if (dump_file && (dump_flags & TDF_DETAILS))
		fprintf (dump_file,
			 "Found xor, "
			 "checking whether it is for CRC calculation.\n");

	      if (xor_calculates_crc (cfun, stmt))
		{
		  dump_crc_information ();
		  free (loop_bbs);
		  return true;
		}

	      if (++checked_xor_count == 2)
		{
		  free (loop_bbs);
		  return false;
		}
	    }
	}
    }
  free (loop_bbs);
  return false;
}

/* Symbolically executes the loop and checks that LFSR and resulting states
   match.
   Returns true if it is verified that the loop calculates CRC.
   Otherwise, return false.
   OUTPUT_CRC is the phi statement which will hold the calculated CRC value
   after the loop exit.  */

bool
crc_optimization::loop_calculates_crc (gphi *output_crc,
				       std::pair<tree, value *> calc_polynom)
{
  /* Create LFSR state using extracted polynomial.  */
  value * lfsr = state::create_lfsr (calc_polynom.first, calc_polynom.second,
				     m_is_bit_forward);
  if (!lfsr)
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "Couldn't create LFSR!\n");
      return false;
    }

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "\nLFSR value is \n");
      state::print_value (lfsr);
    }

  /* Execute the loop with symbolic values
     (symbolic value is assigned to the variable when its value isn't known)
     to keep states, for further comparison.  */
  bool is_crc = true;
  crc_symbolic_execution loop_executor (m_crc_loop, output_crc);
  while (!loop_executor.is_last_iteration ())
    {
      if (!loop_executor.symb_execute_crc_loop ())
	{
	  if (dump_file)
	    fprintf (dump_file, "\nCRC verification didn't succeed "
				"during symbolic execution!\n");
	  is_crc = false;
	  break;
	}

      /* Check whether LFSR and obtained states are same.  */
      tree calculated_crc = PHI_ARG_DEF_FROM_EDGE (output_crc,
						   single_exit (m_crc_loop));
      if (!all_states_match_lfsr (lfsr, m_is_bit_forward, calculated_crc,
				 loop_executor.get_final_states ()))
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file, "Returned state and LFSR differ.\n");
	  is_crc = false;
	  break;
	}
    }
  delete lfsr;
  return is_crc;
}

/* Returns true if OUTPUT_CRC's result is the input of M_PHI_FOR_CRC.
  Otherwise, returns false.  */

bool
crc_optimization::is_output_crc (gphi *output_crc)
{
  tree crc_of_exit
    = PHI_ARG_DEF_FROM_EDGE (output_crc, single_exit (m_crc_loop));
  tree crc_of_latch
    = PHI_ARG_DEF_FROM_EDGE (m_phi_for_crc, loop_latch_edge (m_crc_loop));
  if (crc_of_exit == crc_of_latch)
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "Output CRC is ");
	  print_gimple_expr (dump_file, (gimple *) output_crc, dump_flags);
	  fprintf (dump_file, "\n");
	}
      return true;
    }
  else
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "Output CRC and determined input CRC "
			    "differ.\n");
      return false;
    }
}

/* Swaps M_PHI_FOR_CRC and M_PHI_FOR_DATA if they are mixed.  */

void
crc_optimization::swap_crc_and_data_if_needed (gphi *output_crc)
{
  tree crc_of_exit
    = PHI_ARG_DEF_FROM_EDGE (output_crc, single_exit (m_crc_loop));
  edge crc_loop_latch = loop_latch_edge (m_crc_loop);
  if (crc_of_exit != PHI_ARG_DEF_FROM_EDGE (m_phi_for_crc, crc_loop_latch))
    {
      if (m_phi_for_data
	  && crc_of_exit == PHI_ARG_DEF_FROM_EDGE (m_phi_for_data,
						   crc_loop_latch))
	{
	  std::swap (m_phi_for_crc, m_phi_for_data);
	}
    }
}

/* Validates CRC and data arguments and
   sets them for potential CRC loop replacement.

   The function extracts the CRC and data arguments from PHI nodes and
   performs several checks to ensure that the CRC and data are suitable for
   replacing the CRC loop with a more efficient implementation.

  Returns true if the arguments are valid and the loop replacement is possible,
  false otherwise.  */

bool crc_optimization::validate_crc_and_data ()
{
  /* Set m_crc_arg and check if fits in word_mode.  */
  gcc_assert (m_phi_for_crc);
  m_crc_arg = PHI_ARG_DEF_FROM_EDGE (m_phi_for_crc,
				     loop_preheader_edge (m_crc_loop));
  gcc_assert (m_crc_arg);

  unsigned HOST_WIDE_INT
  data_size = tree_to_uhwi (m_crc_loop->nb_iterations) + 1;
  /* We don't support the case where data is larger than the CRC.  */
  if (TYPE_PRECISION (TREE_TYPE (m_crc_arg)) < data_size)
    return false;

  /* Set m_data_arg if a PHI node for data exists,
     and check its size against loop iterations.
     This is the case when data and CRC are XOR-ed in the loop.  */
  if (m_phi_for_data)
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file,
		 "Data and CRC are xor-ed in the for loop.  Initializing data "
		 "with its value.\n");
      m_data_arg = PHI_ARG_DEF_FROM_EDGE (m_phi_for_data,
					  loop_preheader_edge (m_crc_loop));
      gcc_assert (m_data_arg);
      if (TYPE_PRECISION (TREE_TYPE (m_data_arg)) != data_size)
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file,
		     "Loop iteration number and data's size differ.\n");
	  return false;
	}
	return true;
    }
  return true;
}

/* Convert polynomial to unsigned HOST_WIDE_INT.  */

void
crc_optimization::construct_constant_polynomial (value *polynomial)
{
  m_polynomial = 0;
  for (unsigned i = 0; i < (*polynomial).length (); i++)
    {
      value_bit *const_bit;
      if (m_is_bit_forward)
	const_bit = (*polynomial)[(*polynomial).length () - 1 - i];
      else
	const_bit = (*polynomial)[i];
      m_polynomial <<= 1;
      m_polynomial ^= (as_a<bit *> (const_bit))->get_val () ? 1 : 0;
    }
}

/* Returns phi statement which may hold the calculated CRC.  */

gphi *
crc_optimization::get_output_phi ()
{
  edge loop_exit = single_exit (m_crc_loop);
  if (!loop_exit)
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "The loop doesn't have single exit.\n");
      return nullptr;
    }
  basic_block bb = loop_exit->dest;
  gphi *output_crc = nullptr;
  int phi_count = 0;

  /* We are only interested in cases when there is only one phi at the
   loop exit, and that phi can potentially represent the CRC.
   If there are other phis present, it indicates that additional values are
   being calculated within the loop that are used outside it.  */
  for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
       gsi_next (&gsi))
    {
      tree phi_result = gimple_phi_result (gsi.phi ());

      /* Don't consider virtual operands.  */
      if (!virtual_operand_p (phi_result))
	{
	  if (phi_count < 1)
	    {
	      output_crc = gsi.phi ();
	      phi_count++;
	    }
	  else
	    {
	      if (dump_file && (dump_flags & TDF_DETAILS))
		fprintf (dump_file, "There is more than one output phi.\n");
	      return nullptr;
	    }
	}
    }

  if (output_crc)
    {
      if (gimple_phi_num_args (output_crc) == 1)
	return output_crc;
    }

  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "Couldn't determine output CRC.\n");
  return nullptr;
}

/* Attempts to optimize a CRC calculation loop by replacing it with a call to
   an internal function (IFN_CRC or IFN_CRC_REV).
   Returns true if replacement succeeded, otherwise false.  */

bool
crc_optimization::optimize_crc_loop (class loop *loop, gphi *output_crc)
{
  if (!output_crc)
    {
      if (dump_file)
	fprintf (dump_file, "Couldn't determine output CRC.\n");
      return false;
    }

  if (!m_data_arg)
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file,
		 "Data and CRC are xor-ed before for loop.  Initializing data "
		 "with 0.\n");
      /* Create a new variable for the data.
       Determine the data's size with the loop iteration count.  */
      unsigned HOST_WIDE_INT
	data_size = tree_to_uhwi (m_crc_loop->nb_iterations) + 1;
      tree type = build_nonstandard_integer_type (data_size, 1);
     /* For the CRC calculation, it doesn't matter CRC is calculated for the
	(CRC^data, 0) or (CRC, data).  */
      m_data_arg = build_int_cstu (type, 0);
    }

  /* Build tree node for the polynomial from its constant value.  */
  tree polynomial_arg = build_int_cstu (TREE_TYPE (m_crc_arg), m_polynomial);
  gcc_assert (polynomial_arg);

  internal_fn ifn;
  if (m_is_bit_forward)
    ifn = IFN_CRC;
  else
    ifn = IFN_CRC_REV;

  tree phi_result = gimple_phi_result (output_crc);
  location_t loc;
  loc = EXPR_LOCATION (phi_result);

  /* If the target does not have an expansion for CRC optimally then the table
     based lookup will need at least 255-bytes of RODATA and won't be smaller
     than the original code itself.  */
  if (!optimize_loop_for_speed_p (loop))
    {
      tree data_type = TREE_TYPE (m_data_arg);
      tree result_type = TREE_TYPE (phi_result);
      auto ty_pair = tree_pair (data_type, result_type);
      if (!direct_internal_fn_supported_p (ifn, ty_pair, OPTIMIZE_FOR_BOTH))
	return false;
    }

  /* Add IFN call and write the return value in the phi_result.  */
  gcall *call = gimple_build_call_internal (ifn, 3, m_crc_arg, m_data_arg,
					    polynomial_arg);

  gimple_call_set_lhs (call, phi_result);
  gimple_set_location (call, loc);
  gimple_stmt_iterator si = gsi_after_labels (gimple_bb (output_crc));
  gsi_insert_before (&si, call, GSI_SAME_STMT);

  /* Remove phi statement, which was holding CRC result.  */
  gimple_stmt_iterator tmp_gsi = gsi_for_stmt (output_crc);
  remove_phi_node (&tmp_gsi, false);

  /* Alter the exit condition of the loop to always exit.  */
  gcond* loop_exit_cond = get_loop_exit_condition (m_crc_loop);
  gimple_cond_make_false (loop_exit_cond);
  update_stmt (loop_exit_cond);
  return true;
}

unsigned int
crc_optimization::execute (function *fun)
{
  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "\nExamining %s function.\n",
	     function_name (fun));

  if (number_of_loops (fun) <= 1)
    return 0;

  /* Get loops of the function.  */
  auto loop_list = loops_list (fun, LI_ONLY_INNERMOST);
  for (auto loop: loop_list)
    {
      /* Perform initial checks to filter out non-CRCs.  */
      if (loop_may_calculate_crc (loop))
	{
	  /* Get the phi which will hold the calculated CRC.  */
	  gphi *output_crc = get_output_phi ();
	  if (!output_crc)
	    break;

	  swap_crc_and_data_if_needed (output_crc);
	  if (!is_output_crc (output_crc))
	    break;
	  if (!validate_crc_and_data ())
	    break;

	  edge loop_latch = loop_latch_edge (m_crc_loop);
	  tree calced_crc = PHI_ARG_DEF_FROM_EDGE (m_phi_for_crc, loop_latch);
	  crc_symbolic_execution execute_loop (m_crc_loop, nullptr);
	  /* Execute the loop assigning specific values to CRC and data
	     for extracting the polynomial.  */
	  std::pair <tree, value *>
	      calc_polynom = execute_loop.extract_polynomial (m_phi_for_crc,
							      m_phi_for_data,
							      calced_crc,
							      m_is_bit_forward);

	  value *polynom_value = calc_polynom.second;
	  /* Stop analysis if we couldn't get the polynomial's value.  */
	  if (!polynom_value)
	    break;

	  /* Stop analysis in case optimize_size is specified
	     and table-based would be generated.  This check is only needed for
	     TARGET_CRC case, as polynomial's value isn't known in the
	     beginning.  */
	  construct_constant_polynomial (polynom_value);

	  if (!loop_calculates_crc (output_crc, calc_polynom))
	    break;

	  if (dump_file)
	    fprintf (dump_file, "The loop with %d header BB index "
				"calculates CRC!\n", m_crc_loop->header->index);

	  if (!optimize_crc_loop (loop, output_crc))
	    {
	      if (dump_file)
		fprintf (dump_file, "Couldn't generate faster CRC code.\n");
	    }
	}
    }
  return 0;
}

namespace
{

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

    class pass_crc_optimization : public gimple_opt_pass {
     public:
      pass_crc_optimization (gcc::context *ctxt)
	  : gimple_opt_pass (pass_data_crc_optimization, ctxt)
      {}

      /* opt_pass methods: */
      virtual bool gate (function *)
      {
	return flag_optimize_crc;
      }

      virtual unsigned int execute (function *);

    }; // class pass_crc_optimization

    unsigned int
    pass_crc_optimization::execute (function *fun)
    {
      return crc_optimization ().execute (fun);
    }

} // anon namespace

gimple_opt_pass *
make_pass_crc_optimization (gcc::context *ctxt)
{
  return new pass_crc_optimization (ctxt);
}
