/* An SH specific RTL pass that tries to combine comparisons and redundant
   condition code register stores across multiple basic blocks.
   Copyright (C) 2013-2022 Free Software Foundation, Inc.

This file is part of GCC.

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

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

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

#define IN_TARGET_CODE 1

#include "config.h"
#define INCLUDE_ALGORITHM
#define INCLUDE_LIST
#define INCLUDE_VECTOR
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "memmodel.h"
#include "optabs.h"
#include "emit-rtl.h"
#include "recog.h"
#include "cfgrtl.h"
#include "tree-pass.h"
#include "expr.h"
#include "tm-preds.h"

/*
This pass tries to optimize for example this:
	mov.l	@(4,r4),r1
	tst	r1,r1
	movt	r1
	tst	r1,r1
	bt/s	.L5

into something simpler:
	mov.l	@(4,r4),r1
	tst	r1,r1
	bf/s	.L5

Such sequences can be identified by looking for conditional branches and
checking whether the ccreg is set before the conditional branch
by testing another register for != 0, which was set by a ccreg store.
This can be optimized by eliminating the redundant comparison and
inverting the branch condition.  There can be multiple comparisons in
different basic blocks that all end up in the redunant test insn before the
conditional branch.  Some example RTL ...

Example 1)
----------

[bb 3]
(set (reg:SI 147 t) (eq:SI (reg:SI 173) (const_int 0)))
(set (reg:SI 167) (xor:SI (reg:SI 147 t) (const_int 1)))
-> bb 5

[bb 4]
(set (reg:SI 147 t) (eq:SI (reg:SI 177) (const_int 0)))
(set (reg:SI 167) (reg:SI 147 t))
-> bb 5

[bb 5]
(set (reg:SI 147 t) (eq:SI (reg:SI 167) (const_int 0)))
(set (pc) (if_then_else (ne (reg:SI 147 t) (const_int 0))
                        (label_ref:SI 50) (pc)))

In [bb 4] elimination of the comparison would require inversion of the branch
condition and compensation of other BBs.
Instead the comparison in [bb 3] can be replaced with the comparison in [bb 5]
by using a reg-reg move.  In [bb 4] a logical not is used to compensate the
inverted condition.

[bb 3]
(set (reg:SI 167) (reg:SI 173))
-> bb 5

[BB 4]
(set (reg:SI 147 t) (eq:SI (reg:SI 177) (const_int 0)))
(set (reg:SI 167) (reg:SI 147 t))
-> bb 5

[bb 5]
(set (reg:SI 147 t) (eq:SI (reg:SI 167) (const_int 0)))
(set (pc) (if_then_else (ne (reg:SI 147 t) (const_int 0)))
                        (label_ref:SI 50) (pc)))


Example 2)
----------

[bb 3]
(set (reg:SI 147 t) (gt:SI (reg:SI 173) (reg:SI 175)))
(set (reg:SI 167) (reg:SI 147 t))
-> bb 5

[bb 4]
(set (reg:SI 147 t) (gt:SI (reg:SI 177) (reg:SI 179)))
(set (reg:SI 167) (reg:SI 147 t))
-> bb 5

[bb 5]
(set (reg:SI 147 t) (eq:SI (reg:SI 167) (const_int 0)))
(set (pc) (if_then_else (ne (reg:SI 147 t) (const_int 0))
                        (label_ref:SI 51) (pc)))

The common comparison is factored out and the branch condition is inverted:

[bb 3]
(set (reg:SI 167) (reg:SI 173))
(set (reg:SI 200) (reg:SI 175))
-> bb 5

[bb 4]
(set (reg:SI 167) (reg:SI 177))
(set (reg:SI 200) (reg:SI 179))
-> bb 5

[bb 5]
(set (reg:SI 147 t) (gt:SI (reg:SI 167) (reg:SI 200)))
(set (pc) (if_then_else (eq (reg:SI 147 t) (const_int 0))
                        (label_ref:SI 51) (pc)))


Example 3)
----------

[bb 3]
(set (reg:SI 147 t) (gt:SI (reg:SI 173) (reg:SI 175)))
(set (reg:SI 167) (reg:SI 147 t))
-> bb 5

[bb 4]
(set (reg:SI 147 t) (ge:SI (reg:SI 179) (reg:SI 177)))
(set (reg:SI 167) (reg:SI 147 t))
-> bb 5

[bb 5]
(set (reg:SI 147 t) (eq:SI (reg:SI 167) (const_int 0)))
(set (pc) (if_then_else (ne (reg:SI 147 t) (const_int 0))
                        (label_ref:SI 51) (pc)))

The T bit lifetime is extended and the branch condition is inverted:

[bb 3]
(set (reg:SI 147 t) (gt:SI (reg:SI 173) (reg:SI 175)))
-> bb 5

[bb 4]
(set (reg:SI 147 t) (ge:SI (reg:SI 179) (reg:SI 177)))
-> bb 5

[bb 5]
(set (pc) (if_then_else (eq (reg:SI 147 t) (const_int 0))
                        (label_ref:SI 51) (pc)))


Example 4)
----------

[bb 3]
(set (reg:SI 147 t) (eq:SI (reg:SI 173) (const_int 5)))
(set (reg:SI 167) (reg:SI 147 t))
-> bb 5

[bb 4]
(set (reg:SI 147 t) (eq:SI (reg:SI 176) (const_int 5)))
(set (reg:SI 167) (xor:SI (reg:SI 147 t) (const_int 1)))
-> bb 5

[bb 5]
(set (reg:SI 147 t) (eq:SI (reg:SI 167) (const_int 0)))
(set (pc) (if_then_else (ne (reg:SI 147 t) (const_int 0))
                        (label_ref:SI 50) (pc)))

In this case the comparisons are the same and could be combined, but the
branch condition is different for [bb 3] and [bb 5].  Since the comparison
is not a zero comparison, we can't negate one of the operands.  The best thing
we can do here is to eliminate the comparison before the cbranch and invert
the ccreg in one of the BBs.  On SH2A this will utilize the 'nott' instruction.

[bb 3]
(set (reg:SI 147 t) (eq:SI (reg:SI 173) (const_int 5)))
-> bb 5

[bb 4]
(set (reg:SI 147 t) (eq:SI (reg:SI 176) (const_int 5)))
(set (reg:SI 147 t) (xor:SI (reg:SI 147 t) (const_int 1)))
-> bb 5

[bb 5]
(set (pc) (if_then_else (eq (reg:SI 147 t) (const_int 0))  // inverted
                        (label_ref:SI 50) (pc)))


In order to handle cases such as above the RTL pass does the following:

- Find the ccreg sets (comparisons) and ccreg stores
  (inverting and non-inverting) in all related BBs.

- If the comparison types in the BBs are all the same, try to combine the
  comparisons in the BBs and replace the zero comparison before the cbranch
  with the common comparison.

    - If the cstores are the same, move the comparison before the cbranch
      and replace the comparisons in the BBs with reg-reg copies to get the
      operands in place (create new pseudo regs).

    - If the cstores differ and the comparison is a test against zero,
      use reg-reg copies for the dominating cstores and logical not cstores
      for the subordinate cstores.

- If the comparison types in the BBs are not the same, or the first approach
  doesn't work out for some reason, try to eliminate the comparison before the
  cbranch by extending the lifetime of the ccreg by leaving the individual
  comparisons but eliminating the cstores.
  If the cstores are all the same this is straight forward.
  If they're not, try to reverse the ccreg for the subordinate cstore type
  and eliminate the dominating one.
*/

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// 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)

struct set_of_reg
{
  // The insn where the search stopped or NULL.
  rtx_insn *insn;

  // The set rtx of the specified reg if found, NULL_RTX otherwise.
  // Notice that the set rtx can also be in a parallel.
  const_rtx set_rtx;

  // The set source operand rtx if found, NULL_RTX otherwise.
  rtx
  set_src (void) const
  {
    return set_rtx == NULL_RTX ? NULL_RTX : XEXP (set_rtx, 1);
  }

  // The set destination operand rtx if found, NULL_RTX otherwise.
  rtx
  set_dst (void) const
  {
    return set_rtx == NULL_RTX ? NULL_RTX : XEXP (set_rtx, 0);
  }

  bool
  empty (void) const
  {
    return insn == NULL_RTX || set_rtx == NULL_RTX;
  }
};

// Given a reg rtx and a start insn find the insn (in the same basic block)
// that sets the reg.
static set_of_reg
find_set_of_reg_bb (rtx reg, rtx_insn *insn)
{
  set_of_reg result = { insn, NULL_RTX };

  if (!REG_P (reg) || insn == NULL)
    return result;

  for (result.insn = insn; result.insn != NULL;
       result.insn = prev_nonnote_nondebug_insn_bb (result.insn))
    {
      if (BARRIER_P (result.insn))
	return result;
      if (!NONJUMP_INSN_P (result.insn))
	continue;
      if (reg_set_p (reg, result.insn))
	{
	  result.set_rtx = set_of (reg, result.insn);
	  if (result.set_rtx == NULL_RTX || GET_CODE (result.set_rtx) != SET)
	    result.set_rtx = NULL_RTX;
	  return result;
	}
    }

  return result;
}

static bool
reg_dead_after_insn (const_rtx reg, const_rtx insn)
{
  return find_regno_note (insn, REG_DEAD, REGNO (reg)) != NULL_RTX;
}

static bool
reg_unused_after_insn (const_rtx reg, const_rtx insn)
{
  return find_regno_note (insn, REG_UNUSED, REGNO (reg)) != NULL_RTX;
}

// Check whether the two specified basic blocks are adjacent, i.e. there's no
// other basic block in between them.
static bool
is_adjacent_bb (basic_block a, basic_block b)
{
  basic_block bb0[] = { a, b };
  basic_block bb1[] = { b, a };

  for (int i = 0; i < 2; ++i)
    for (edge_iterator ei = ei_start (bb0[i]->succs);
	 !ei_end_p (ei); ei_next (&ei))
      if (ei_edge (ei)->dest == bb1[i])
	return true;

  return false;
}

// Internal function of trace_reg_uses.
static void
trace_reg_uses_1 (rtx reg, rtx_insn *start_insn, basic_block bb, int& count,
		  std::vector<basic_block>& visited_bb, rtx abort_at_insn)
{
  if (bb == NULL)
    return;

  if (std::find (visited_bb.begin (), visited_bb.end (), bb)
      != visited_bb.end ())
    log_return_void ("[bb %d] already visited\n", bb->index);

  visited_bb.push_back (bb);

  if (BB_END (bb) == NULL_RTX)
    log_return_void ("[bb %d] BB_END is null\n", bb->index);

  if (start_insn == NULL_RTX)
    log_return_void ("[bb %d] start_insn is null\n", bb->index);

  rtx end_insn = NEXT_INSN (BB_END (bb));
  if (end_insn == NULL_RTX)
    log_return_void ("[bb %d] end_insn is null\n", bb->index);

  for (rtx_insn *i = NEXT_INSN (start_insn); i != end_insn; i = NEXT_INSN (i))
    {
      if (INSN_P (i))
	{
	  if (NONDEBUG_INSN_P (i)
	      && (reg_overlap_mentioned_p (reg, PATTERN (i))
		  || (CALL_P (i) && find_reg_fusage (i, USE, reg))))
	    {
	      log_msg ("found use in [bb %d] at insn:\n", bb->index);
	      log_insn (i);
	      log_msg ("\n");
	      count += 1;
	    }

	  // Stop following this BB if the reg is set or dies along the way.
	  if (reg_set_p (reg, i) || reg_dead_after_insn (reg, i))
	    return;
	}

      if (abort_at_insn != NULL_RTX && abort_at_insn == i)
	return;
    }

  for (edge_iterator ei = ei_start (bb->succs); !ei_end_p (ei); ei_next (&ei))
    {
      basic_block succ_bb = ei_edge (ei)->dest;
      trace_reg_uses_1 (reg, BB_HEAD (succ_bb), succ_bb, count, visited_bb,
			abort_at_insn);
    }
}

// Trace uses of the specified reg in all basic blocks that are reachable from
// the specified insn.  If 'abort_at_insn' is not null, abort the trace at
// that insn.  If the insn 'abort_at_insn' uses the specified reg, it is also
// counted.
static int
trace_reg_uses (rtx reg, rtx_insn *start_insn, rtx abort_at_insn)
{
  log_msg ("\ntrace_reg_uses\nreg = ");
  log_rtx (reg);
  log_msg ("\nstart_insn = ");
  log_insn (start_insn);

  int count = 0;
  std::vector<basic_block> visited_bb;
  visited_bb.reserve (32);

  trace_reg_uses_1 (reg, start_insn, BLOCK_FOR_INSN (start_insn),
		    count, visited_bb, abort_at_insn);
  return count;
}

static bool
is_conditional_insn (rtx_insn* i)
{
  if (! (INSN_P (i) && NONDEBUG_INSN_P (i)))
    return false;

  rtx p = PATTERN (i);
  return GET_CODE (p) == SET && GET_CODE (XEXP (p, 1)) == IF_THEN_ELSE;
}

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

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

private:
  // Type of ccreg store that is supported.
  enum cstore_type_t
  {
    cstore_normal = 0,
    cstore_inverted = 1,
    cstore_unknown = -1
  };

  // Type of branch condition that is supported.
  enum branch_condition_type_t
  {
    branch_if_true = 1,
    branch_if_false = 0,
    unknown_branch_condition = -1
  };

  // For each basic block there can be a trace entry which consists of an
  // insn that sets the ccreg (usually a comparison) and a ccreg store.
  struct bb_entry
  {
    basic_block bb;
    set_of_reg setcc;
    set_of_reg cstore;
    cstore_type_t cstore_type;
    std::vector<set_of_reg> cstore_reg_reg_copies;

    bb_entry (basic_block b)
    : bb (b), setcc (), cstore (), cstore_type (cstore_unknown) { }

    rtx comparison_rtx (void) const { return setcc.set_src (); }
  };

  // A ccreg trace for a conditional branch.
  struct cbranch_trace
  {
    rtx_insn *cbranch_insn;
    rtx* condition_rtx_in_insn;
    branch_condition_type_t cbranch_type;

    // The comparison against zero right before the conditional branch.
    set_of_reg setcc;

    // All BBs that are related to the cbranch.  The last BB in the list is
    // the BB of the cbranch itself and might be empty.
    std::list<bb_entry> bb_entries;

    cbranch_trace (rtx_insn *insn)
    : cbranch_insn (insn),
      condition_rtx_in_insn (NULL),
      cbranch_type (unknown_branch_condition),
      setcc ()
    {
      if (is_conditional_insn (cbranch_insn))
	condition_rtx_in_insn = &XEXP (XEXP (PATTERN (cbranch_insn), 1), 0);
      else if (rtx x = pc_set (cbranch_insn))
	condition_rtx_in_insn = &XEXP (XEXP (x, 1), 0);
    }

    basic_block bb (void) const { return BLOCK_FOR_INSN (cbranch_insn); }

    rtx
    branch_condition_rtx (void) const
    {
      return condition_rtx_in_insn != NULL ? *condition_rtx_in_insn : NULL;
    }
    rtx&
    branch_condition_rtx_ref (void) const
    {
      // Before anything gets to invoke this function, there are other checks
      // in place to make sure that we have a known branch condition and thus
      // the ref to the rtx in the insn.
      gcc_assert (condition_rtx_in_insn != NULL);
      return *condition_rtx_in_insn;
    }

    bool
    can_invert_condition (void) const
    {
      // The branch condition can be inverted safely only if the condition
      // reg is dead after the cbranch.
      return reg_dead_after_insn (XEXP (branch_condition_rtx (), 0),
				  cbranch_insn);
    }
  };

  static const pass_data default_pass_data;

  // Tells whether modified or newly added insns are to be split at the end
  // of the pass.
  const bool m_split_insns;

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

  // Newly added or modified insns.
  std::vector<rtx> m_touched_insns;

  // Given an rtx determine whether it's a comparison with a constant zero.
  static bool is_cmp_eq_zero (const_rtx i);

  // Update the stored mode of the ccreg from the given branch condition rtx.
  void update_ccreg_mode (const_rtx cond);

  // Given an rtx, figure out the branch condition, assuming that it is
  // in canonical form:
  //   (ne (reg) (const_int 0))
  //   (eq (reg) (const_int 0))
  branch_condition_type_t branch_condition_type (const_rtx cond) const;

  // Return true if the specified rtx is either a normal ccreg or
  // a negated form of the ccreg.
  bool is_normal_ccreg (const_rtx x) const;
  bool is_inverted_ccreg (const_rtx x) const;

  // Given a reg rtx and a start insn rtx, try to find the insn in the same
  // basic block that sets the specified reg.
  // Return how the search ended and the insn where it stopped or NULL_RTX.
  enum record_return_t
  {
    set_found,
    set_not_found,
    other_set_found
  };
  record_return_t record_set_of_reg (rtx reg, rtx_insn *start_insn,
                                     bb_entry& e);

  // Tells whether the cbranch insn of the specified bb_entry can be removed
  // safely without triggering any side effects.
  bool can_remove_cstore (const bb_entry& e,
			  const cbranch_trace& trace) const;

  // Tells whether the setcc insn of the specified bb_entry can be removed
  // safely without triggering any side effects.
  bool can_remove_comparison (const bb_entry& e,
			      const cbranch_trace& trace) const;

  // Tells whether the two specified comparison rtx can be combined into a
  // single comparison.
  bool can_combine_comparisons (const_rtx x, const_rtx y) const;

  // Tells whether the ccreg usage can be extended from the bb_entry on until
  // the final cbranch of the trace.
  bool can_extend_ccreg_usage (const bb_entry& e,
			       const cbranch_trace& trace) const;

  // Create an insn rtx that performs a logical not (test != 0) on the src_reg
  // and stores the result in dst_reg.
  rtx make_not_reg_insn (rtx dst_reg, rtx src_reg) const;

  // Create an insn rtx that inverts the ccreg.
  rtx_insn *make_inv_ccreg_insn (void) const;

  // Adds the specified insn to the set of modified or newly added insns that
  // might need splitting at the end of the pass.
  rtx touched_insn (rtx i);

  // Try to invert the branch condition of the specified trace.
  bool try_invert_branch_condition (cbranch_trace& trace);

  // Try to optimize a cbranch trace by combining comparisons in BBs and
  // eliminate the cstores.
  bool try_combine_comparisons (cbranch_trace& trace,
				int cstore_count, int inv_cstore_count,
				cstore_type_t dominating_cstore);

  // Try to optimize a cbranch trace by eliminating the cstores in BBs only.
  bool try_eliminate_cstores (cbranch_trace& trace,
			      int cstore_count, int inv_cstore_count,
			      cstore_type_t dominating_cstore);

  // Given a branch insn, try to optimize its branch condition.
  // If any insns are modified or added they are added to 'm_touched_insns'.
  void try_optimize_cbranch (rtx_insn *i);
};


const pass_data sh_treg_combine::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
  TODO_df_finish | TODO_df_verify	// todo_flags_finish
};

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

sh_treg_combine::~sh_treg_combine (void)
{
}

void sh_treg_combine::update_ccreg_mode (const_rtx cond)
{
  if (REG_P (XEXP (cond, 0)) && REGNO (XEXP (cond, 0)) != REGNO (m_ccreg))
    return;

  machine_mode m = GET_MODE (XEXP (cond, 0));
  if (m == GET_MODE (m_ccreg))
    return;

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

bool
sh_treg_combine::is_cmp_eq_zero (const_rtx i)
{
  return i != NULL_RTX && GET_CODE (i) == EQ
	 && REG_P (XEXP (i, 0)) && XEXP (i, 1) == const0_rtx;
}

sh_treg_combine::branch_condition_type_t
sh_treg_combine::branch_condition_type (const_rtx cond) const
{
  if (cond == NULL_RTX)
    return unknown_branch_condition;

  if (GET_CODE (cond) == NE
      && REG_P (XEXP (cond, 0)) && REGNO (XEXP (cond, 0)) == REGNO (m_ccreg)
      && XEXP (cond, 1) == const0_rtx)
    return 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)
    return branch_if_false;

  else
    return unknown_branch_condition;
}

bool
sh_treg_combine::is_normal_ccreg (const_rtx x) const
{
  return t_reg_operand (const_cast<rtx> (x), VOIDmode);
}

bool
sh_treg_combine::is_inverted_ccreg (const_rtx x) const
{
  return negt_reg_operand (const_cast<rtx> (x), VOIDmode);
}

sh_treg_combine::record_return_t
sh_treg_combine::record_set_of_reg (rtx reg, rtx_insn *start_insn,
				    bb_entry& new_entry)
{
  log_msg ("\n[bb %d]\n", new_entry.bb->index);

  if (start_insn == NULL_RTX)
    log_return (set_not_found, "set of reg not found.  empty BB?\n");

  new_entry.cstore_type = cstore_unknown;

  for (rtx_insn *i = start_insn; i != NULL; )
    {
      new_entry.cstore = find_set_of_reg_bb (reg, i);

      if (new_entry.cstore.set_src () == NULL_RTX)
	log_return (set_not_found, "set of reg not found (cstore)\n");

      log_insn (new_entry.cstore.insn);
      log_msg ("\n");

      if (is_normal_ccreg (new_entry.cstore.set_src ()))
	{
	  log_msg ("normal condition store\n");
	  new_entry.cstore_type = cstore_normal;
	}
      else if (is_inverted_ccreg (new_entry.cstore.set_src ()))
	{
	  log_msg ("inverted condition store\n");
	  new_entry.cstore_type = cstore_inverted;
	}
      else if (REG_P (new_entry.cstore.set_src ()))
	{
	  // If it's a reg-reg copy follow the copied reg.
	  new_entry.cstore_reg_reg_copies.push_back (new_entry.cstore);
	  reg = new_entry.cstore.set_src ();
	  i = new_entry.cstore.insn;

	  log_msg ("reg-reg copy.  tracing ");
	  log_rtx (reg);
	  log_msg ("\n");
	  continue;
	}
      else
	log_return (other_set_found, "not a condition store\n");

      gcc_assert (new_entry.cstore_type != cstore_unknown);

      // Now see how the ccreg was set.
      // For now it must be in the same BB.
      log_msg ("tracing ccreg\n");
      new_entry.setcc = find_set_of_reg_bb
	(m_ccreg, prev_nonnote_nondebug_insn_bb (new_entry.cstore.insn));

      // If cstore was found but setcc was not found continue anyway, as
      // for some of the optimization types the setcc is irrelevant.
      if (new_entry.setcc.set_src () == NULL_RTX)
	log_return (set_found, "set of ccreg not found\n");

      else if (GET_CODE (new_entry.setcc.set_rtx) == SET)
	{
	  // Also allow insns that set the ccreg, but are not true comparison
	  // insns, as long as they are sets and not e.g. clobbers.
	  log_insn (new_entry.setcc.insn);
	  log_msg ("\n");
	  return set_found;
	}
      else
	// If cstore was found but setcc was not found continue anyway, as
	// for some of the optimization types the setcc is irrelevant.
 	log_return (set_found, "unknown set of ccreg\n");
    }

  log_return (set_not_found, "set of reg not found\n");
}

bool
sh_treg_combine::can_remove_cstore (const bb_entry& e,
				    const cbranch_trace& trace) const
{
  if (volatile_insn_p (PATTERN (e.cstore.insn)))
    {
      log_msg ("can't remove insn\n");
      log_insn (e.cstore.insn);
      log_return (false, "\nbecause it's volatile\n");
    }

  // On SH there are parallel patterns which store the ccreg multiple times.
  // In this case it's not safe.
  rtx cstore_pat = PATTERN (e.cstore.insn);
  if (GET_CODE (cstore_pat) == PARALLEL)
    for (int i = 0; i < XVECLEN (cstore_pat, 0); ++i)
      {
	rtx x = XVECEXP (cstore_pat, 0, i);

	// It's the cstore set that we're referring to, ignore that one.
	if (x != e.cstore.set_rtx
	    && GET_CODE (x) == SET && reg_referenced_p (m_ccreg, x))
	  {
	    log_msg ("can't remove insn\n");
	    log_insn (e.cstore.insn);
	    log_return (false, "\nbecause it's a multiple ccreg store\n");
	  }
      }

  // If the cstore sets the ccreg (e.g. negc) and the ccreg is used afterwards
  // it's not safe.
  if (modified_in_p (m_ccreg, e.cstore.insn)
      && !(reg_dead_after_insn (m_ccreg, e.cstore.insn)
	   || reg_unused_after_insn (m_ccreg, e.cstore.insn)))
    {
      log_msg ("can't remove insn\n");
      log_insn (e.cstore.insn);
      log_return (false, "\nbecause it sets the ccreg\n");
    }

  // If the cstore destination reg is copied around check the reg-reg
  // copies.  At every reg-reg copy the copied reg must be dead and there
  // must not be a usage of the copied regs between the reg-reg copies.
  // Otherwise we assume that the result of the cstore is used in some
  // other way.
  rtx_insn *prev_insn = e.cstore.insn;
  for (std::vector<set_of_reg>::const_reverse_iterator i =
	   e.cstore_reg_reg_copies.rbegin ();
       i != e.cstore_reg_reg_copies.rend (); ++i)
    {
      if (!reg_dead_after_insn (i->set_src (), i->insn))
	{
	  log_msg ("can't remove insn\n");
	  log_insn (i->insn);
	  log_return (false, "\nbecause source of reg-reg copy doesn't die\n");
	}

     if (reg_used_between_p (i->set_src (), prev_insn, i->insn))
	{
	  log_msg ("can't remove insn\n");
	  log_insn (i->insn);
	  log_return (false, "\nbecause reg %d is otherwise used\n",
			     REGNO (i->set_src ()));
	}

      prev_insn = i->insn;
    }

  // The cstore_dst reg must die after the test before the cbranch, otherwise
  // it's not safe to remove the cstore.
  // If the cstore destination reg is copied around check the effective
  // destination reg of the cstore.  The reg-reg copies are recorded in
  // reverse order, i.e. the most recent reg-reg copy in the insn list
  // comes first.
  rtx cstore_dst = e.cstore_reg_reg_copies.empty ()
		   ? e.cstore.set_dst ()
		   : e.cstore_reg_reg_copies.front ().set_dst ();

  if (!reg_dead_after_insn (cstore_dst, trace.setcc.insn))
    {
      log_msg ("can't remove insn\n");
      log_insn (e.cstore.insn);
      log_return (false, "\nbecause its effective target reg %d doesn't die "
			 "after trace.setcc.insn\n", REGNO (cstore_dst));
    }

  // Also check that the cstore_dst reg is not used in other reachable code
  // paths before it dies.
  // Count the uses of the effective cstore_dst reg (i.e. the last known reg
  // that holds the cstore value after reg-reg copies) in all BBs that can be
  // reached from bb_entry's BB including the BB of the cstore insn.
  // If we get more than 1 uses we assume that it's used somewhere else and is
  // not safe to be removed.
  int cstore_dst_use_count = trace_reg_uses (cstore_dst, e.cstore.insn,
					     trace.setcc.insn);
  if (cstore_dst_use_count > 1)
    {
      log_msg ("can't remove insn\n");
      log_insn (e.cstore.insn);
      log_return (false, "\nbecause its effective target reg %d is used "
			 "in %d other places\n", REGNO (cstore_dst),
			  cstore_dst_use_count - 1);
    }

  return true;
}

bool
sh_treg_combine::can_remove_comparison (const bb_entry& e,
					const cbranch_trace&/* trace*/) const
{
  // If the ccreg is used otherwise between the comparison and the cstore,
  // it's not safe.
  if (reg_used_between_p (m_ccreg, e.setcc.insn, e.cstore.insn))
    {
      log_msg ("can't remove insn\n");
      log_insn (e.setcc.insn);
      log_return (false, "\nbecause the ccreg is used otherwise\n");
    }

  if (!reg_dead_after_insn (m_ccreg, e.cstore.insn)
      && !reg_unused_after_insn (m_ccreg, e.cstore.insn))
    {
      log_msg ("can't remove insn\n");
      log_insn (e.cstore.insn);
      log_return (false, "\nbecause ccreg is not dead or unused afterwards\n");
    }

  // On SH there are also multiple set patterns that can be used for
  // comparisons, such as "shll".  It's not safe to remove those.
  if (multiple_sets (e.setcc.insn))
    {
      log_msg ("can't remove insn\n");
      log_insn (e.cstore.insn);
      log_return (false, "\nbecause it's a multiple set\n");
    }

  return true;
}

rtx
sh_treg_combine::make_not_reg_insn (rtx dst_reg, rtx src_reg) const
{
  // On SH we can do only SImode and DImode comparisons.
  if (! (GET_MODE (src_reg) == SImode || GET_MODE (src_reg) == DImode))
    return NULL;

  // On SH we can store the ccreg into an SImode or DImode reg only.
  if (! (GET_MODE (dst_reg) == SImode || GET_MODE (dst_reg) == DImode))
    return NULL;

  start_sequence ();

  emit_insn (gen_rtx_SET (m_ccreg, gen_rtx_fmt_ee (EQ, SImode,
						   src_reg, const0_rtx)));

  if (GET_MODE (dst_reg) == SImode)
    emit_move_insn (dst_reg, m_ccreg);
  else if (GET_MODE (dst_reg) == DImode)
    {
      emit_move_insn (gen_lowpart (SImode, dst_reg), m_ccreg);
      emit_move_insn (gen_highpart (SImode, dst_reg), const0_rtx);
    }
  else
    gcc_unreachable ();

  rtx i = get_insns ();
  end_sequence ();

  return i;
}

rtx_insn *
sh_treg_combine::make_inv_ccreg_insn (void) const
{
  start_sequence ();
  rtx_insn *i = emit_insn (gen_rtx_SET (m_ccreg,
                                        gen_rtx_fmt_ee (XOR, GET_MODE (m_ccreg),
                                                        m_ccreg, const1_rtx)));
  end_sequence ();
  return i;
}

rtx
sh_treg_combine::touched_insn (rtx i)
{
  m_touched_insns.push_back (i);
  return i;
}

bool
sh_treg_combine::can_combine_comparisons (const_rtx x, const_rtx y) const
{
  if (GET_CODE (x) != GET_CODE (y))
    return false;

  rtx x_op0 = XEXP (x, 0);
  rtx x_op1 = XEXP (x, 1);

  rtx y_op0 = XEXP (y, 0);
  rtx y_op1 = XEXP (y, 1);

  if (!REG_P (x_op0) || !REG_P (y_op0))
    return false;

  if (GET_MODE (x_op0) != GET_MODE (y_op0))
    return false;

  // rtx_equal_p also compares the reg numbers which we do not care about
  // here, as long as both are regs and the modes are the same.
  if (REG_P (x_op1))
    return REG_P (y_op1) && GET_MODE (x_op1) == GET_MODE (y_op1);

  return rtx_equal_p (x_op1, y_op1);
}

bool
sh_treg_combine::can_extend_ccreg_usage (const bb_entry& e,
					 const cbranch_trace& trace) const
{
  // Check if the ccreg is not modified by other insins in the BB path until
  // the final cbranch of the trace.
  // Start checking after the cstore that follows the setcc, assuming that
  // the cstore will be removed.

  // The assumption here is that the specified bb_entry's BB is a direct
  // predecessor of the trace.cbranch_insn's BB.
  if (e.bb != trace.bb () && !is_adjacent_bb (e.bb, trace.bb ()))
    log_return (false,
	"can't extend ccreg usage -- [bb %d] and [bb %d] are not adjacent\n",
	e.bb->index, trace.bb ()->index);

  if (e.cstore.empty ())
    log_return (false, "can't extend ccreg usage -- no cstore\n");

  // The entry's cstore is in the same BB as the final cbranch.
  if (e.bb == trace.bb ())
    {
      if (reg_set_between_p (m_ccreg, e.cstore.insn, trace.setcc.insn))
	log_return (false,
	    "can't extend ccreg usage -- it's modified between e.cstore.insn "
	    "and trace.setcc.insn");
      else
	return true;
    }

  // The entry's cstore and the final cbranch are in different BBs.
  if (reg_set_between_p (m_ccreg, e.cstore.insn, NEXT_INSN (BB_END (e.bb))))
    log_return (false,
	"can't extend ccreg usage -- it's modified in [bb %d]", e.bb->index);

  if (reg_set_between_p (m_ccreg, PREV_INSN (BB_HEAD (trace.bb ())),
			 trace.setcc.insn))
    log_return (false,
	"can't extend ccreg usage -- it's modified in [bb %d]",
	trace.bb ()->index);

  return true;
}

bool
sh_treg_combine::try_invert_branch_condition (cbranch_trace& trace)
{
  log_msg ("inverting branch condition\n");

  rtx& comp = trace.branch_condition_rtx_ref ();

  rtx_code rev_cmp_code = reversed_comparison_code (comp, trace.cbranch_insn);

  if (rev_cmp_code == UNKNOWN)
    log_return (false, "reversed_comparison_code = UNKNOWN\n");

  validate_change (trace.cbranch_insn, &comp,
		   gen_rtx_fmt_ee (rev_cmp_code,
				   GET_MODE (comp), XEXP (comp, 0),
				   XEXP (comp, 1)),
		   1);

  if (verify_changes (num_validated_changes ()))
    confirm_change_group ();
  else
    log_return (false, "verify_changed failed\n");

  touched_insn (trace.cbranch_insn);
  return true;
}

bool
sh_treg_combine::try_combine_comparisons (cbranch_trace& trace,
					  int cstore_count,
					  int inv_cstore_count,
					  cstore_type_t dominating_cstore)
{
  log_msg ("\ntry_combine_comparisons\n");

  // This function will always try to create new pseudos.
  if (!can_create_pseudo_p ())
    log_return (false, "can't create pseudos\n");

  // Check that all ccset insns are comparisons and all comparison types in
  // all BBs are the same and could be combined into one single comparison.
  rtx comp = NULL_RTX;
  rtx comp_insn = NULL_RTX;

  for (std::list<bb_entry>::const_iterator i = trace.bb_entries.begin ();
       i != trace.bb_entries.end (); ++i)
    {
      int i_empty_count = i->setcc.empty () + i->cstore.empty ();

      // A completly empty entry is OK (could be the BB of the cbranch).
      if (i_empty_count == 2)
	continue;

      // Otherwise we need both, the setcc and the cstore.
      if (i_empty_count != 0)
	log_return (false, "bb entry is not a setcc cstore pair\n");

      rtx other_comp = i->comparison_rtx ();

      if (!COMPARISON_P (other_comp))
	{
	  log_msg ("setcc is not a comparison:\n");
	  log_rtx (other_comp);
	  log_return (false, "\n");
	}

      if (comp_insn == NULL_RTX)
	{
	  comp = other_comp;
	  comp_insn = i->setcc.insn;
	}
      else if (!can_combine_comparisons (comp, other_comp))
	return false;

      // The goal here is to eliminate all cstores and comparisons in the BBs.
      // Thus check if every cstore can actually be removed safely.
      if (!can_remove_cstore (*i, trace) || !can_remove_comparison (*i, trace))
	return false;
    }

  // FIXME: The first operand of the comparison must be a simple reg.
  // This effectively prohibits combining div0s comparisons such as
  //    (lt:SI (xor:SI (reg:SI) (reg:SI)))
  if (!REG_P (XEXP (comp, 0)))
    {
      log_msg ("comparison operand 0\n");
      log_rtx (XEXP (comp, 0));
      log_return (false, "\nis not a reg\n");
    }

  rtx comp_op0 = gen_reg_rtx (GET_MODE (XEXP (comp, 0)));
  rtx comp_op1 = REG_P (XEXP (comp, 1))
		 ? gen_reg_rtx (GET_MODE (XEXP (comp, 1)))
		 : XEXP (comp, 1);

  // If there are both, inverting and non-inverting cstores, they can only
  // be eliminated if the comparison can be inverted.  We assume that the
  // comparison insns that we find are already minimal and canonicalized.
  // There is one special case though, where an integer comparison
  //     (eq (reg) (const_int 0))
  // can be inverted with a sequence
  //     (set (t) (eq (reg) (const_int 0))
  //     (set (reg) (t))
  //     (eq (reg) (const_int 0))
  //
  // FIXME: On SH2A it might be better to use the nott insn in this case,
  // i.e. do the try_eliminate_cstores approach instead.
  if (inv_cstore_count != 0 && cstore_count != 0)
    {
      if (make_not_reg_insn (comp_op0, comp_op0) == NULL_RTX)
	log_return (false, "make_not_reg_insn failed.\n");

      for (std::list<bb_entry>::const_iterator i = trace.bb_entries.begin ();
	   i != trace.bb_entries.end (); ++i)
	{
	  if (i->setcc.empty () || i->cstore.empty ())
	    continue;

	  if (i->cstore_type != dominating_cstore
	      && !is_cmp_eq_zero (i->comparison_rtx ()))
	    {
	      log_msg ("can't invert comparison in insn\n");
	      log_insn (i->setcc.insn);
	      log_return (false,
		"\nbecause it's not a (eq (reg) (const_int 0))\n");
	    }
	}
    }

  if (dominating_cstore == cstore_normal
      && !try_invert_branch_condition (trace))
    return false;

  // Replace the test insn before the cbranch with the common comparison.
  // Instead of creating a new insn from scratch we copy the common comparison
  // pattern.  This simplifies handling parallel comparison patterns, such as
  // FP comparisons on SH, which have an extra use on FPSCR.
  log_msg ("installing common comparison in [bb %d]\n", trace.bb ()->index);

  rtx common_comp_pat = copy_rtx (PATTERN (comp_insn));
  rtx common_comp = const_cast<rtx> (set_of (m_ccreg, common_comp_pat));

  gcc_assert (common_comp != NULL_RTX);

  XEXP (XEXP (common_comp, 1), 0) = comp_op0;
  XEXP (XEXP (common_comp, 1), 1) = comp_op1;

  log_rtx (common_comp_pat);
  log_msg ("\n");

  rtx common_comp_insn = touched_insn (emit_insn_after (common_comp_pat,
							trace.setcc.insn));

  if (REG_P (comp_op0))
    add_reg_note (common_comp_insn, REG_DEAD, copy_rtx (comp_op0));
  if (REG_P (comp_op1))
    add_reg_note (common_comp_insn, REG_DEAD, copy_rtx (comp_op1));

  delete_insn (trace.setcc.insn);

  // Replace comparison and cstore insns with reg-reg moves in all BBs.
  for (std::list<bb_entry>::const_iterator i = trace.bb_entries.begin ();
       i != trace.bb_entries.end (); ++i)
    {
      if (i->setcc.empty () || i->cstore.empty ())
	continue;

      rtx i_comp_op0 = XEXP (i->comparison_rtx (), 0);
      rtx i_comp_op1 = XEXP (i->comparison_rtx (), 1);

      if (i->cstore_type == dominating_cstore)
	{
	  log_msg ("replacing comparison and cstore with reg move "
		   "in [bb %d]\n", i->bb->index);

	  rtx new_i = touched_insn (
		emit_insn_after (gen_move_insn (comp_op0, i_comp_op0),
				 i->setcc.insn));

	  if (REG_P (i_comp_op0)
	      && reg_dead_after_insn (i_comp_op0, i->setcc.insn))
	    add_reg_note (new_i, REG_DEAD, copy_rtx (i_comp_op0));

	  // If the second operand is a reg, have to emit a move insn.
	  // Otherwise assume it's a const_int and just reference it.
	  if (REG_P (comp_op1))
	    {
	      new_i = touched_insn (
		  emit_insn_after (gen_move_insn (comp_op1, i_comp_op1),
				   i->setcc.insn));

	      if (reg_dead_after_insn (i_comp_op1, i->setcc.insn))
		add_reg_note (new_i, REG_DEAD, copy_rtx (i_comp_op1));
	    }
	}
      else
	{
	  log_msg ("replacing comparison and cstore with inverting reg move "
		   "in [bb %d]\n", i->bb->index);

	  rtx new_i = make_not_reg_insn (comp_op0, i_comp_op0);
	  if (REG_P (i_comp_op0)
	      && reg_dead_after_insn (i_comp_op0, i->setcc.insn))
	    add_reg_note (new_i, REG_DEAD, copy_rtx (i_comp_op0));

	  touched_insn (emit_insn_after (new_i, i->setcc.insn));
	}

      delete_insn (i->cstore.insn);
      delete_insn (i->setcc.insn);
    }

  return true;
}

bool
sh_treg_combine::try_eliminate_cstores (cbranch_trace& trace,
					int cstore_count, int inv_cstore_count,
					cstore_type_t dominating_cstore)
{
  log_msg ("\ntry_eliminate_cstores\n");

  for (std::list<bb_entry>::const_iterator i = trace.bb_entries.begin ();
       i != trace.bb_entries.end (); ++i)
    {
      // A completly empty entry is OK (could be the BB of the cbranch).
      if (i->setcc.empty () && i->cstore.empty ())
	continue;

      // We're going to eliminate cstores, but for that they have to be
      // there.  We don't care about the setcc in this case.
      if (i->cstore.empty ())
	log_return (false, "bb entry cstore empty -- aborting\n");

      // The goal here is to eliminate all cstores in the BBs and extend the
      // ccreg usage.
      if (!can_extend_ccreg_usage (*i, trace))
	return false;

      // If the cstore can't be removed we can keep it around as long as
      // it doesn't modify the ccreg.
      if (!can_remove_cstore (*i, trace)
	  && modified_in_p (m_ccreg, i->cstore.insn))
	log_return (false, "cstore sets ccreg -- aborting\n");
    }

  // If there are both, inverting and non-inverting cstores, we'll have to
  // invert the ccreg as a replacement for one of them.
  if (cstore_count != 0 && inv_cstore_count != 0)
    {
      rtx_insn *i = make_inv_ccreg_insn ();
      if (recog_memoized (i) < 0)
	{
	  log_msg ("failed to match ccreg inversion insn:\n");
	  log_rtx (PATTERN (i));
	  log_return (false, "\naborting\n");
	}
    }

  if (dominating_cstore == cstore_normal
      && !try_invert_branch_condition (trace))
    return false;

  // Eliminate cstores in all BBs.
  for (std::list<bb_entry>::const_iterator i = trace.bb_entries.begin ();
       i != trace.bb_entries.end (); ++i)
    {
      if (i->cstore.empty ())
	continue;

      if (i->cstore_type == dominating_cstore)
	log_msg ("removing cstore in [bb %d]\n", i->bb->index);
      else
	{
	  log_msg ("replacing cstore with ccreg inversion in [bb %d]\n",
		   i->bb->index);

	  touched_insn (
	    emit_insn_after (make_inv_ccreg_insn (), i->cstore.insn));
	}

      if (can_remove_cstore (*i, trace))
	delete_insn (i->cstore.insn);
    }

  log_msg ("removing test insn before cbranch\n");
  delete_insn (trace.setcc.insn);
  return true;
}

void
sh_treg_combine::try_optimize_cbranch (rtx_insn *insn)
{
  cbranch_trace trace (insn);

  log_msg ("\n\n--------------------------------------\n");
  log_msg ("found cbranch insn in [bb %d]:\n", trace.bb ()->index);
  log_insn (insn);

  trace.cbranch_type = branch_condition_type (trace.branch_condition_rtx ());

  if (trace.cbranch_type == branch_if_true)
    log_msg ("condition: branch if true\n");
  else if (trace.cbranch_type == branch_if_false)
    log_msg ("condition: branch if false\n");
  else
    {
      log_msg ("unknown branch condition\n");
      log_rtx (trace.branch_condition_rtx ());
      log_return_void ("\n");
    }

  update_ccreg_mode (trace.branch_condition_rtx ());

  // Scan the insns backwards for an insn that sets the ccreg by testing a
  // reg against zero like
  //   (set (reg ccreg) (eq (reg) (const_int 0)))
  // The testing insn could also be outside of the current basic block, but
  // for now we limit the search to the current basic block.
  trace.setcc = find_set_of_reg_bb
    (m_ccreg, prev_nonnote_nondebug_insn_bb (insn));

  if (trace.setcc.set_src () == NULL_RTX)
    log_return_void ("could not find set of ccreg in current BB\n");

  if (!is_cmp_eq_zero (trace.setcc.set_src ())
      && !is_inverted_ccreg (trace.setcc.set_src ()))
    {
      log_msg ("unsupported set of ccreg in current BB: ");
      log_rtx (trace.setcc.set_src ());
      log_return_void ("\n");
    }

  rtx trace_reg = XEXP (trace.setcc.set_src (), 0);

  log_msg ("set of ccreg:\n");
  log_insn (trace.setcc.insn);

  // See if we can remove the trace.setcc insn safely.
  if (reg_used_between_p (m_ccreg, trace.setcc.insn, trace.cbranch_insn))
    log_return_void ("ccreg used between testing insn and branch insn\n");

  if (volatile_insn_p (PATTERN (trace.setcc.insn)))
    {
      log_msg ("can't remove insn\n");
      log_insn (trace.setcc.insn);
      log_return_void ("\nbecause it's volatile\n");
    }

  // If the ccreg is inverted before cbranch try inverting the branch
  // condition.
  if (is_inverted_ccreg (trace.setcc.set_src ()))
    {
      if (!trace.can_invert_condition ())
	log_return_void ("branch condition can't be inverted - aborting\n");

      if (try_invert_branch_condition (trace))
	delete_insn (trace.setcc.insn);

      return;
    }

  // Now that we have an insn which tests some reg and sets the condition
  // reg before the conditional branch, try to figure out how that tested
  // reg was formed, i.e. find all the insns that set the tested reg in
  // some way.
  // The tested reg might be set in multiple basic blocks so we need to
  // check all basic blocks which can reach this current basic block.
  // If the set of reg is an inverting or non-inverting store of the condition
  // register, check how the ccreg value was obtained.
  log_msg ("\ntracing ");
  log_rtx (trace_reg);
  log_msg ("\n");


  // First check the basic block where the conditional branch is in.
  // If we find it here there's no point in checking other BBs.
  trace.bb_entries.push_front (bb_entry (trace.bb ()));

  record_return_t res = record_set_of_reg
    (trace_reg, prev_nonnote_nondebug_insn_bb (trace.setcc.insn),
     trace.bb_entries.front ());

  if (res == other_set_found)
    log_return_void ("other set found - aborting trace\n");
  else if (res == set_not_found)
    {
      // It seems the initial search in the BB of the conditional branch
      // didn't find anything.  Now look in all predecessor BBs.
      for (edge_iterator ei = ei_start (trace.bb ()->preds);
	   !ei_end_p (ei); ei_next (&ei))
	{
	  edge e = ei_edge (ei);
	  trace.bb_entries.push_front (bb_entry (e->src));

	  res = record_set_of_reg (trace_reg, BB_END (e->src),
				   trace.bb_entries.front ());
	  if (res != set_found)
	    log_return_void ("set not found - aborting trace\n");
	}
    }

  if (dump_file != NULL)
    {
      log_msg ("\ncbranch trace summary:\n");
      for (std::list<bb_entry>::const_iterator i = trace.bb_entries.begin ();
	   i != trace.bb_entries.end (); ++i)
	{
	  log_msg ("\n[bb %d]\n", i->bb->index);
	  if (!i->setcc.empty ())
	    {
	      log_rtx (i->setcc.set_rtx);
	      log_msg ("\n");
	    }
	  if (!i->cstore.empty ())
	    {
	      log_rtx (i->cstore.set_rtx);
	      log_msg ("\n");
	    }

	  for (std::vector<set_of_reg>::const_reverse_iterator j =
		   i->cstore_reg_reg_copies.rbegin ();
	       j != i->cstore_reg_reg_copies.rend (); ++j)
	    {
	      log_rtx (j->set_rtx);
	      log_msg ("\n");
	    }
	}

      log_rtx (trace.setcc.set_rtx);
      log_msg ("\n");
      log_rtx (PATTERN (trace.cbranch_insn));
      log_msg ("\n");
    }

  // Check that we don't have any empty BBs.
  // Only the BB with the cbranch may be empty.
  for (std::list<bb_entry>::const_iterator i = trace.bb_entries.begin ();
       i != trace.bb_entries.end (); ++i)
    if (i->setcc.empty () && i->cstore.empty () && i->bb != trace.bb ())
      log_return_void ("\n[bb %d] is empty - aborting.\n", i->bb->index);

  // Determine the dominating cstore type
  // FIXME: Try to take the probabilities of the BBs into account somehow.
  int cstore_count = 0;
  int inv_cstore_count = 0;

  for (std::list<bb_entry>::const_iterator i = trace.bb_entries.begin ();
       i != trace.bb_entries.end (); ++i)
    {
      if (i->cstore_type == cstore_normal)
	cstore_count += 1;
      else if (i->cstore_type == cstore_inverted)
	inv_cstore_count += 1;
    }

  log_msg ("cstore count = %d  inverted cstore count = %d\n",
	   cstore_count, inv_cstore_count);

  // This puts a priority on inverting cstores.
  cstore_type_t dominating_cstore = inv_cstore_count >= cstore_count
				    ? cstore_inverted
				    : cstore_normal;

  if (dominating_cstore == cstore_inverted)
      log_msg ("will try to eliminate inverted cstore\n");
  else if (dominating_cstore == cstore_normal)
    {
      log_msg ("will try to eliminate normal cstore\n");
      if (!trace.can_invert_condition ())
	log_return_void ("branch condition can't be inverted - aborting\n");
    }
  else
    gcc_unreachable ();

  if (try_combine_comparisons (trace, cstore_count, inv_cstore_count,
			       dominating_cstore))
    return;

  try_eliminate_cstores (trace, cstore_count, inv_cstore_count,
			 dominating_cstore);
}

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

unsigned int
sh_treg_combine::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 first conditional branch 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);

  // Look for basic blocks that end with a conditional branch or for
  // conditional insns and try to optimize them.
  basic_block bb;
  FOR_EACH_BB_FN (bb, fun)
    {
      rtx_insn* i = BB_END (bb);
      if (i == NULL || i == PREV_INSN (BB_HEAD (bb)))
	continue;

      // A conditional branch is always the last insn of a basic block.
      if (any_condjump_p (i) && onlyjump_p (i))
	{
	  try_optimize_cbranch (i);
	  i = PREV_INSN (i);
	}

      // Check all insns in block for conditional insns.
      for (; i != NULL && i != PREV_INSN (BB_HEAD (bb)); i = PREV_INSN (i))
	if (is_conditional_insn (i))
	  try_optimize_cbranch (i);
    }

  log_msg ("\n\n");

  // If new insns are created and this pass is executed after all insns
  // have been split already, we must split the insns we've changed or added
  // ourselves here.
  // FIXME: Multi-word operations (which emit multiple insns) are not handled
  // properly here, since only one insn will end up in 'm_touched_insns'.
  // On SH this is not a problem though.
  if (m_split_insns)
    for (std::vector<rtx>::const_iterator i = m_touched_insns.begin ();
	 i != m_touched_insns.end (); ++i)
      {
	log_msg ("trying to split insn:\n");
	log_insn (*i);
	log_msg ("\n");
	try_split (PATTERN (*i), safe_as_a <rtx_insn *> (*i), 0);
      }

  m_touched_insns.clear ();
  log_return (0, "\n\n");
}

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