/* An SH specific RTL pass that tries to optimize clrt and sett insns.
   Copyright (C) 2013-2021 Free Software Foundation, Inc.

This file is part of GCC.

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

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

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

#define IN_TARGET_CODE 1

#include "config.h"
#define INCLUDE_ALGORITHM
#define INCLUDE_VECTOR
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "df.h"
#include "cfgrtl.h"
#include "tree-pass.h"

/*
This pass tries to eliminate unnecessary sett or clrt instructions in cases
where the ccreg value is already known to be the same as the constant set
would set it to.  This is done as follows:

Check every BB's insn and see if it's a sett or clrt.
Once a sett or clrt insn is hit, walk insns and predecessor basic blocks
backwards from that insn and determine all possible ccreg values from all
basic block paths.
Insns that set the ccreg value in some way (simple set, clobber etc) are
recorded.  Conditional branches where one edge leads to the sett / clrt insn
are also recorded, since for each edge in the conditional branch the ccreg
value is known constant.
After collecting all possible ccreg values at the sett / clrt insn, check that
all the values are the same.  If that value is the same as the sett / clrt
insn would set the ccreg to, the sett / clrt insn can be eliminated.
*/


// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Helper functions

#define log_msg(...)\
  do { if (dump_file != NULL) fprintf (dump_file, __VA_ARGS__); } while (0)

#define log_insn(i)\
  do { if (dump_file != NULL) print_rtl_single (dump_file, \
						(const_rtx)i); } while (0)

#define log_rtx(r)\
  do { if (dump_file != NULL) print_rtl (dump_file, (const_rtx)r); } while (0)

#define log_return(retval, ...)\
  do { if (dump_file != NULL) fprintf (dump_file, __VA_ARGS__); \
       return retval; } while (0)

#define log_return_void(...)\
  do { if (dump_file != NULL) fprintf (dump_file, __VA_ARGS__); \
       return; } while (0)

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// RTL pass class

class sh_optimize_sett_clrt : public rtl_opt_pass
{
public:
  sh_optimize_sett_clrt (gcc::context* ctx, const char* name);
  virtual ~sh_optimize_sett_clrt (void);
  virtual bool gate (function*);
  virtual unsigned int execute (function* fun);

private:
  static const pass_data default_pass_data;

  struct ccreg_value
  {
    // The insn at which the ccreg value was determined.
    // Might be NULL if e.g. an unknown value is recorded for an
    // empty basic block.
    rtx_insn *insn;

    // The basic block where the insn was discovered.
    basic_block bb;

    // The value of ccreg.  If NULL_RTX, the exact value is not known, but
    // the ccreg is changed in some way (e.g. clobbered).
    rtx value;
  };

  // Update the mode of the captured m_ccreg with the specified mode.
  void update_ccreg_mode (machine_mode m);

  // Given an insn pattern, check if it sets the ccreg to a constant value
  // of either zero or STORE_FLAG_VALUE.  If so, return the value rtx,
  // NULL_RTX otherwise.
  rtx const_setcc_value (rtx pat) const;

  // Given a start insn and its basic block, recursively determine all
  // possible ccreg values in all basic block paths that can lead to the
  // start insn.
  bool find_last_ccreg_values (rtx_insn *start_insn, basic_block bb,
			       std::vector<ccreg_value>& values_out,
			       std::vector<basic_block>& prev_visited_bb) const;

  // Given a cbranch insn, its basic block and another basic block, determine
  // the value to which the ccreg will be set after jumping/falling through to
  // the specified target basic block.
  bool sh_cbranch_ccreg_value (rtx_insn *cbranch_insn,
			       basic_block cbranch_insn_bb,
			       basic_block branch_target_bb) const;

  // Check whether all of the ccreg values are the same.
  static bool all_ccreg_values_equal (const std::vector<ccreg_value>& values);

  // Remove REG_DEAD and REG_UNUSED notes from insns of the specified
  // ccreg_value entries.
  void remove_ccreg_dead_unused_notes (std::vector<ccreg_value>& values) const;

  // rtx of the ccreg that is obtained from the target.
  rtx m_ccreg;
};

const pass_data sh_optimize_sett_clrt::default_pass_data =
{
  RTL_PASS,		// type
  "",			// name (overwritten by the constructor)
  OPTGROUP_NONE,	// optinfo_flags
  TV_OPTIMIZE,		// tv_id
  0,			// properties_required
  0,			// properties_provided
  0,			// properties_destroyed
  0,			// todo_flags_start
  0			// todo_flags_finish
};

sh_optimize_sett_clrt::sh_optimize_sett_clrt (gcc::context* ctx,
					      const char* name)
: rtl_opt_pass (default_pass_data, ctx),
  m_ccreg (NULL_RTX)
{
  // Overwrite default name in pass_data base class.
  this->name = name;
}

sh_optimize_sett_clrt::~sh_optimize_sett_clrt (void)
{
}

bool
sh_optimize_sett_clrt::gate (function*)
{
  return optimize > 0;
}

unsigned int
sh_optimize_sett_clrt::execute (function* fun)
{
  unsigned int ccr0 = INVALID_REGNUM;
  unsigned int ccr1 = INVALID_REGNUM;

  if (targetm.fixed_condition_code_regs (&ccr0, &ccr1)
      && ccr0 != INVALID_REGNUM)
    {
      // Initially create a reg rtx with VOIDmode.
      // When the constant setcc is discovered, the mode is changed
      // to the mode that is actually used by the target.
      m_ccreg = gen_rtx_REG (VOIDmode, ccr0);
    }

  if (m_ccreg == NULL_RTX)
    log_return (0, "no ccreg.\n\n");

  if (STORE_FLAG_VALUE != 1)
    log_return (0, "unsupported STORE_FLAG_VALUE %d", STORE_FLAG_VALUE);

  log_msg ("ccreg: ");
  log_rtx (m_ccreg);
  log_msg ("  STORE_FLAG_VALUE = %d\n", STORE_FLAG_VALUE);

  if (!df_regs_ever_live_p (ccr0))
    log_return (0, "ccreg never live\n\n");

  // Output vector for find_known_ccreg_values.
  std::vector<ccreg_value> ccreg_values;
  ccreg_values.reserve (32);

  // Something for recording visited basic blocks to avoid infinite recursion.
  std::vector<basic_block> visited_bbs;
  visited_bbs.reserve (32);

  // Look for insns that set the ccreg to a constant value and see if it can
  // be optimized.
  basic_block bb;
  FOR_EACH_BB_REVERSE_FN (bb, fun)
    for (rtx_insn *next_i, *i = NEXT_INSN (BB_HEAD (bb));
	 i != NULL_RTX && i != BB_END (bb); i = next_i)
      {
	next_i = NEXT_INSN (i);

	if (!INSN_P (i) || !NONDEBUG_INSN_P (i))
	  continue;

	rtx setcc_val = const_setcc_value (PATTERN (i));
	if (setcc_val != NULL_RTX)
	  {
	    update_ccreg_mode (GET_MODE (XEXP (PATTERN (i), 0)));

	    log_msg ("\n\nfound const setcc insn in [bb %d]: \n", bb->index);
	    log_insn (i);
	    log_msg ("\n");

	    ccreg_values.clear ();
	    visited_bbs.clear ();
	    bool ok = find_last_ccreg_values (PREV_INSN (i), bb, ccreg_values,
					      visited_bbs);

	    log_msg ("number of ccreg values collected: %u\n",
		     (unsigned int)ccreg_values.size ());

	    // If all the collected values are equal and are equal to the
	    // constant value of the setcc insn, the setcc insn can be
	    // removed.
	    if (ok && all_ccreg_values_equal (ccreg_values)
		&& rtx_equal_p (ccreg_values.front ().value, setcc_val))
	      {
		log_msg ("all values are ");
		log_rtx (setcc_val);
		log_msg ("\n");

		delete_insn (i);
		remove_ccreg_dead_unused_notes (ccreg_values);
	      }
	  }
      }

  log_return (0, "\n\n");
}

void
sh_optimize_sett_clrt::update_ccreg_mode (machine_mode m)
{
  if (GET_MODE (m_ccreg) == m)
    return;

  PUT_MODE (m_ccreg, m);
  log_msg ("updated ccreg mode: ");
  log_rtx (m_ccreg);
  log_msg ("\n\n");
}

rtx
sh_optimize_sett_clrt::const_setcc_value (rtx pat) const
{
  if (GET_CODE (pat) == SET
      && REG_P (XEXP (pat, 0)) && REGNO (XEXP (pat, 0)) == REGNO (m_ccreg)
      && CONST_INT_P (XEXP (pat, 1))
      && (INTVAL (XEXP (pat, 1)) == 0
	  || INTVAL (XEXP (pat, 1)) == STORE_FLAG_VALUE))
    return XEXP (pat, 1);
  else
    return NULL_RTX;
}

bool
sh_optimize_sett_clrt
::sh_cbranch_ccreg_value (rtx_insn *cbranch_insn, basic_block cbranch_insn_bb,
			  basic_block branch_target_bb) const
{
  rtx pc_set_rtx = pc_set (cbranch_insn);
  gcc_assert (pc_set_rtx != NULL_RTX);
  gcc_assert (branch_target_bb != NULL);

  rtx cond = XEXP (XEXP (pc_set_rtx, 1), 0);
  bool branch_if;

  if (GET_CODE (cond) == NE
      && REG_P (XEXP (cond, 0)) && REGNO (XEXP (cond, 0)) == REGNO (m_ccreg)
      && XEXP (cond, 1) == const0_rtx)
    branch_if = true;

  else if (GET_CODE (cond) == EQ
      && REG_P (XEXP (cond, 0)) && REGNO (XEXP (cond, 0)) == REGNO (m_ccreg)
      && XEXP (cond, 1) == const0_rtx)
    branch_if = false;

  else
    gcc_unreachable ();

  if (branch_target_bb == BRANCH_EDGE (cbranch_insn_bb)->dest)
    return branch_if;
  else if (branch_target_bb == FALLTHRU_EDGE (cbranch_insn_bb)->dest)
    return !branch_if;
  else
    gcc_unreachable ();
}

bool
sh_optimize_sett_clrt
::find_last_ccreg_values (rtx_insn *start_insn, basic_block bb,
			  std::vector<ccreg_value>& values_out,
			  std::vector<basic_block>& prev_visited_bb) const
{
  // FIXME: For larger CFGs this will unnecessarily re-visit basic blocks.
  // Once a basic block has been visited, the result should be stored in
  // some container so that it can be looked up quickly eliminating the
  // re-visits.
  log_msg ("looking for ccreg values in [bb %d] ", bb->index);
  if (!prev_visited_bb.empty ())
    log_msg ("(prev visited [bb %d])", prev_visited_bb.back ()->index);
  log_msg ("\n");

  for (rtx_insn *i = start_insn; i != NULL && i != PREV_INSN (BB_HEAD (bb));
       i = PREV_INSN (i))
    {
      if (!INSN_P (i))
	continue;

      if (reg_set_p (m_ccreg, i))
	{
	  const_rtx set_rtx = set_of (m_ccreg, i);

	  ccreg_value v;
	  v.insn = i;
	  v.bb = bb;
	  v.value = set_rtx != NULL_RTX && GET_CODE (set_rtx) == SET
		    ? XEXP (set_rtx, 1)
		    : NULL_RTX;

	  log_msg ("found setcc in [bb %d] in insn:\n", bb->index);
	  log_insn (i);
	  log_msg ("\nccreg value: ");
	  log_rtx (v.value);
	  log_msg ("\n");

	  values_out.push_back (v);
	  return true;
	}

      if (any_condjump_p (i) && onlyjump_p (i) && !prev_visited_bb.empty ())
	{
	  // For a conditional branch the ccreg value will be a known constant
	  // of either 0 or STORE_FLAG_VALUE after branching/falling through
	  // to one of the two successor BBs.  Record the value for the BB
	  // where we came from.
	  log_msg ("found cbranch in [bb %d]:\n", bb->index);
	  log_insn (i);

	  ccreg_value v;
	  v.insn = i;
	  v.bb = bb;
	  v.value = GEN_INT (sh_cbranch_ccreg_value (i, bb,
						     prev_visited_bb.back ()));

	  log_msg ("    branches to [bb %d] with ccreg value ",
		   prev_visited_bb.back ()->index);
	  log_rtx (v.value);
	  log_msg ("\n");

	  values_out.push_back (v);
	  return true;
	}
    }

  // If here, we've walked up all the insns of the current basic block
  // and none of them seems to modify the ccreg.
  // In this case, check the predecessor basic blocks.
  unsigned int pred_bb_count = 0;

  // If the current basic block is not in the stack of previously visited
  // basic blocks yet, we can recursively check the predecessor basic blocks.
  // Otherwise we have a loop in the CFG and recursing again will result in
  // an infinite loop.
  if (std::find (prev_visited_bb.rbegin (), prev_visited_bb.rend (), bb)
      == prev_visited_bb.rend ())
    {
      prev_visited_bb.push_back (bb);

      for (edge_iterator ei = ei_start (bb->preds); !ei_end_p (ei);
	   ei_next (&ei))
	{
	  if (ei_edge (ei)->flags & EDGE_COMPLEX)
	    log_return (false, "aborting due to complex edge\n");

	  basic_block pred_bb = ei_edge (ei)->src;
	  pred_bb_count += 1;
	  if (!find_last_ccreg_values (BB_END (pred_bb), pred_bb, values_out,
				       prev_visited_bb))
	    return false;
	}

      prev_visited_bb.pop_back ();
    }
  else
    log_msg ("loop detected for [bb %d]\n", bb->index);

  log_msg ("[bb %d] pred_bb_count = %u\n", bb->index, pred_bb_count);

  if (pred_bb_count == 0)
  {
    // If we haven't checked a single predecessor basic block, the current
    // basic block is probably a leaf block and we don't know the ccreg value.
    log_msg ("unknown ccreg value for [bb %d]\n", bb->index);

    ccreg_value v;
    v.insn = BB_END (bb);
    v.bb = bb;
    v.value = NULL_RTX;

    values_out.push_back (v);
  }

  return true;
}

bool
sh_optimize_sett_clrt
::all_ccreg_values_equal (const std::vector<ccreg_value>& values)
{
  if (values.empty ())
    return false;

  rtx last_value = values.front ().value;

  // If the ccreg is modified in the insn but the exact value is not known
  // the value rtx might be null.
  if (last_value == NULL_RTX)
    return false;

  for (std::vector<ccreg_value>::const_iterator i = values.begin ();
       i != values.end (); ++i)
    if (i->value == NULL_RTX || !rtx_equal_p (last_value, i->value))
      return false;

  return true;
}

void
sh_optimize_sett_clrt
::remove_ccreg_dead_unused_notes (std::vector<ccreg_value>& values) const
{
  for (std::vector<ccreg_value>::iterator i = values.begin ();
       i != values.end (); ++i)
    {
      if (i->insn == NULL_RTX)
	continue;

      rtx n = find_regno_note (i->insn, REG_DEAD, REGNO (m_ccreg));
      if (n != NULL_RTX)
	remove_note (i->insn, n);

      n = find_regno_note (i->insn, REG_UNUSED, REGNO (m_ccreg));
      if (n != NULL_RTX)
	remove_note (i->insn, n);
    }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// This allows instantiating the pass somewhere else without having to pull
// in a header file.
opt_pass*
make_pass_sh_optimize_sett_clrt (gcc::context* ctx, const char* name)
{
  return new sh_optimize_sett_clrt (ctx, name);
}
