/* Tree switch conversion for GNU compiler.
   Copyright (C) 2017-2019 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/>.  */

#ifndef TREE_SWITCH_CONVERSION_H
#define TREE_SWITCH_CONVERSION_H

namespace tree_switch_conversion {

/* Type of cluster.  */

enum cluster_type
{
  SIMPLE_CASE,
  JUMP_TABLE,
  BIT_TEST
};

#define PRINT_CASE(f,c) print_generic_expr (f, c)

/* Abstract base class for representing a cluster of cases.

   Here is the inheritance hierarachy, and the enum_cluster_type
   values for the concrete subclasses:

   cluster
   |-simple_cluster (SIMPLE_CASE)
   `-group_cluster
     |-jump_table_cluster (JUMP_TABLE)
     `-bit_test_cluster   (BIT_TEST).  */

struct cluster
{
  /* Constructor.  */
  cluster (tree case_label_expr, basic_block case_bb, profile_probability prob,
	   profile_probability subtree_prob);

  /* Destructor.  */
  virtual ~cluster ()
  {}

  /* Return type.  */
  virtual cluster_type get_type () = 0;

  /* Get low value covered by a cluster.  */
  virtual tree get_low () = 0;

  /* Get high value covered by a cluster.  */
  virtual tree get_high () = 0;

  /* Debug content of a cluster.  */
  virtual void debug () = 0;

  /* Dump content of a cluster.  */
  virtual void dump (FILE *f, bool details = false) = 0;

  /* Emit GIMPLE code to handle the cluster.  */
  virtual void emit (tree, tree, tree, basic_block, location_t) = 0;

  /* Return true if a cluster handles only a single case value and the
     value is not a range.  */
  virtual bool is_single_value_p ()
  {
    return false;
  }

  /* Return range of a cluster.  If value would overflow in type of LOW,
     then return 0.  */
  static unsigned HOST_WIDE_INT get_range (tree low, tree high)
  {
    tree r = fold_build2 (MINUS_EXPR, TREE_TYPE (low), high, low);
    if (!tree_fits_uhwi_p (r))
      return 0;

    return tree_to_uhwi (r) + 1;
  }

  /* Case label.  */
  tree m_case_label_expr;

  /* Basic block of the case.  */
  basic_block m_case_bb;

  /* Probability of taking this cluster.  */
  profile_probability m_prob;

  /* Probability of reaching subtree rooted at this node.  */
  profile_probability m_subtree_prob;

protected:
  /* Default constructor.  */
  cluster () {}
};

cluster::cluster (tree case_label_expr, basic_block case_bb,
		  profile_probability prob, profile_probability subtree_prob):
  m_case_label_expr (case_label_expr), m_case_bb (case_bb), m_prob (prob),
  m_subtree_prob (subtree_prob)
{
}

/* Subclass of cluster representing a simple contiguous range
   from [low..high].  */

struct simple_cluster: public cluster
{
  /* Constructor.  */
  simple_cluster (tree low, tree high, tree case_label_expr,
		  basic_block case_bb, profile_probability prob);

  /* Destructor.  */
  ~simple_cluster ()
  {}

  cluster_type
  get_type ()
  {
    return SIMPLE_CASE;
  }

  tree
  get_low ()
  {
    return m_low;
  }

  tree
  get_high ()
  {
    return m_high;
  }

  void
  debug ()
  {
    dump (stderr);
  }

  void
  dump (FILE *f, bool details ATTRIBUTE_UNUSED = false)
  {
    PRINT_CASE (f, get_low ());
    if (get_low () != get_high ())
      {
	fprintf (f, "-");
	PRINT_CASE (f, get_high ());
      }
    fprintf (f, " ");
  }

  void emit (tree, tree, tree, basic_block, location_t)
  {
    gcc_unreachable ();
  }

  bool is_single_value_p ()
  {
    return tree_int_cst_equal (get_low (), get_high ());
  }

  /* Low value of the case.  */
  tree m_low;

  /* High value of the case.  */
  tree m_high;

  /* True if case is a range.  */
  bool m_range_p;
};

simple_cluster::simple_cluster (tree low, tree high, tree case_label_expr,
				basic_block case_bb, profile_probability prob):
  cluster (case_label_expr, case_bb, prob, prob),
  m_low (low), m_high (high)
{
  m_range_p = m_high != NULL;
  if (m_high == NULL)
    m_high = m_low;
}

/* Abstract subclass of jump table and bit test cluster,
   handling a collection of simple_cluster instances.  */

struct group_cluster: public cluster
{
  /* Constructor.  */
  group_cluster (vec<cluster *> &clusters, unsigned start, unsigned end);

  /* Destructor.  */
  ~group_cluster ();

  tree
  get_low ()
  {
    return m_cases[0]->get_low ();
  }

  tree
  get_high ()
  {
    return m_cases[m_cases.length () - 1]->get_high ();
  }

  void
  debug ()
  {
    dump (stderr);
  }

  void dump (FILE *f, bool details = false);

  /* List of simple clusters handled by the group.  */
  vec<simple_cluster *> m_cases;
};

/* Concrete subclass of group_cluster representing a collection
   of cases to be implemented as a jump table.
   The "emit" vfunc gernerates a nested switch statement which
   is later lowered to a jump table.  */

struct jump_table_cluster: public group_cluster
{
  /* Constructor.  */
  jump_table_cluster (vec<cluster *> &clusters, unsigned start, unsigned end)
  : group_cluster (clusters, start, end)
  {}

  cluster_type
  get_type ()
  {
    return JUMP_TABLE;
  }

  void emit (tree index_expr, tree index_type,
	     tree default_label_expr, basic_block default_bb, location_t loc);

  /* Find jump tables of given CLUSTERS, where all members of the vector
     are of type simple_cluster.  New clusters are returned.  */
  static vec<cluster *> find_jump_tables (vec<cluster *> &clusters);

  /* Return true when cluster starting at START and ending at END (inclusive)
     can build a jump-table.  */
  static bool can_be_handled (const vec<cluster *> &clusters, unsigned start,
			      unsigned end);

  /* Return true if cluster starting at START and ending at END (inclusive)
     is profitable transformation.  */
  static bool is_beneficial (const vec<cluster *> &clusters, unsigned start,
			     unsigned end);

  /* Return the smallest number of different values for which it is best
     to use a jump-table instead of a tree of conditional branches.  */
  static inline unsigned int case_values_threshold (void);

  /* Return whether jump table expansion is allowed.  */
  static bool is_enabled (void);

  /* Max growth ratio for code that is optimized for size.  */
  static const unsigned HOST_WIDE_INT max_ratio_for_size = 3;

  /* Max growth ratio for code that is optimized for speed.  */
  static const unsigned HOST_WIDE_INT max_ratio_for_speed = 8;
};

/* A GIMPLE switch statement can be expanded to a short sequence of bit-wise
comparisons.  "switch(x)" is converted into "if ((1 << (x-MINVAL)) & CST)"
where CST and MINVAL are integer constants.  This is better than a series
of compare-and-banch insns in some cases,  e.g. we can implement:

	if ((x==4) || (x==6) || (x==9) || (x==11))

as a single bit test:

	if ((1<<x) & ((1<<4)|(1<<6)|(1<<9)|(1<<11)))

This transformation is only applied if the number of case targets is small,
if CST constains at least 3 bits, and "1 << x" is cheap.  The bit tests are
performed in "word_mode".

The following example shows the code the transformation generates:

	int bar(int x)
	{
		switch (x)
		{
		case '0':  case '1':  case '2':  case '3':  case '4':
		case '5':  case '6':  case '7':  case '8':  case '9':
		case 'A':  case 'B':  case 'C':  case 'D':  case 'E':
		case 'F':
			return 1;
		}
		return 0;
	}

==>

	bar (int x)
	{
		tmp1 = x - 48;
		if (tmp1 > (70 - 48)) goto L2;
		tmp2 = 1 << tmp1;
		tmp3 = 0b11111100000001111111111;
		if ((tmp2 & tmp3) != 0) goto L1 ; else goto L2;
	L1:
		return 1;
	L2:
		return 0;
	}

TODO: There are still some improvements to this transformation that could
be implemented:

* A narrower mode than word_mode could be used if that is cheaper, e.g.
  for x86_64 where a narrower-mode shift may result in smaller code.

* The compounded constant could be shifted rather than the one.  The
  test would be either on the sign bit or on the least significant bit,
  depending on the direction of the shift.  On some machines, the test
  for the branch would be free if the bit to test is already set by the
  shift operation.

This transformation was contributed by Roger Sayle, see this e-mail:
   http://gcc.gnu.org/ml/gcc-patches/2003-01/msg01950.html
*/

struct bit_test_cluster: public group_cluster
{
  /* Constructor.  */
  bit_test_cluster (vec<cluster *> &clusters, unsigned start, unsigned end,
		    bool handles_entire_switch)
  :group_cluster (clusters, start, end),
  m_handles_entire_switch (handles_entire_switch)
  {}

  cluster_type
  get_type ()
  {
    return BIT_TEST;
  }

/*  Expand a switch statement by a short sequence of bit-wise
    comparisons.  "switch(x)" is effectively converted into
    "if ((1 << (x-MINVAL)) & CST)" where CST and MINVAL are
    integer constants.

    INDEX_EXPR is the value being switched on.

    MINVAL is the lowest case value of in the case nodes,
    and RANGE is highest value minus MINVAL.  MINVAL and RANGE
    are not guaranteed to be of the same type as INDEX_EXPR
    (the gimplifier doesn't change the type of case label values,
    and MINVAL and RANGE are derived from those values).
    MAXVAL is MINVAL + RANGE.

    There *MUST* be max_case_bit_tests or less unique case
    node targets.  */
  void emit (tree index_expr, tree index_type,
	     tree default_label_expr, basic_block default_bb, location_t loc);

  /* Find bit tests of given CLUSTERS, where all members of the vector
     are of type simple_cluster.  New clusters are returned.  */
  static vec<cluster *> find_bit_tests (vec<cluster *> &clusters);

  /* Return true when RANGE of case values with UNIQ labels
     can build a bit test.  */
  static bool can_be_handled (unsigned HOST_WIDE_INT range, unsigned uniq);

  /* Return true when cluster starting at START and ending at END (inclusive)
     can build a bit test.  */
  static bool can_be_handled (const vec<cluster *> &clusters, unsigned start,
			      unsigned end);

  /* Return true when COUNT of cases of UNIQ labels is beneficial for bit test
     transformation.  */
  static bool is_beneficial (unsigned count, unsigned uniq);

  /* Return true if cluster starting at START and ending at END (inclusive)
     is profitable transformation.  */
  static bool is_beneficial (const vec<cluster *> &clusters, unsigned start,
			     unsigned end);

/* Split the basic block at the statement pointed to by GSIP, and insert
   a branch to the target basic block of E_TRUE conditional on tree
   expression COND.

   It is assumed that there is already an edge from the to-be-split
   basic block to E_TRUE->dest block.  This edge is removed, and the
   profile information on the edge is re-used for the new conditional
   jump.

   The CFG is updated.  The dominator tree will not be valid after
   this transformation, but the immediate dominators are updated if
   UPDATE_DOMINATORS is true.

   Returns the newly created basic block.  */
  static basic_block hoist_edge_and_branch_if_true (gimple_stmt_iterator *gsip,
						    tree cond,
						    basic_block case_bb,
						    profile_probability prob,
						    location_t);

  /* True when the jump table handles an entire switch statement.  */
  bool m_handles_entire_switch;

  /* Maximum number of different basic blocks that can be handled by
     a bit test.  */
  static const int m_max_case_bit_tests = 3;
};

/* Helper struct to find minimal clusters.  */

struct min_cluster_item
{
  /* Constructor.  */
  min_cluster_item (unsigned count, unsigned start, unsigned non_jt_cases):
    m_count (count), m_start (start), m_non_jt_cases (non_jt_cases)
  {}

  /* Count of clusters.  */
  unsigned m_count;

  /* Index where is cluster boundary.  */
  unsigned m_start;

  /* Total number of cases that will not be in a jump table.  */
  unsigned m_non_jt_cases;
};

/* Helper struct to represent switch decision tree.  */

struct case_tree_node
{
  /* Empty Constructor.  */
  case_tree_node ();

  /* Return true when it has a child.  */
  bool has_child ()
  {
    return m_left != NULL || m_right != NULL;
  }

  /* Left son in binary tree.  */
  case_tree_node *m_left;

  /* Right son in binary tree; also node chain.  */
  case_tree_node *m_right;

  /* Parent of node in binary tree.  */
  case_tree_node *m_parent;

  /* Cluster represented by this tree node.  */
  cluster *m_c;
};

inline
case_tree_node::case_tree_node ():
  m_left (NULL), m_right (NULL), m_parent (NULL), m_c (NULL)
{
}

unsigned int
jump_table_cluster::case_values_threshold (void)
{
  unsigned int threshold = PARAM_VALUE (PARAM_CASE_VALUES_THRESHOLD);

  if (threshold == 0)
    threshold = targetm.case_values_threshold ();

  return threshold;
}

/* Return whether jump table expansion is allowed.  */
bool jump_table_cluster::is_enabled (void)
{
  /* If neither casesi or tablejump is available, or flag_jump_tables
     over-ruled us, we really have no choice.  */
  if (!targetm.have_casesi () && !targetm.have_tablejump ())
    return false;
  if (!flag_jump_tables)
    return false;
#ifndef ASM_OUTPUT_ADDR_DIFF_ELT
  if (flag_pic)
    return false;
#endif

  return true;
}

/* A case_bit_test represents a set of case nodes that may be
   selected from using a bit-wise comparison.  HI and LO hold
   the integer to be tested against, TARGET_EDGE contains the
   edge to the basic block to jump to upon success and BITS
   counts the number of case nodes handled by this test,
   typically the number of bits set in HI:LO.  The LABEL field
   is used to quickly identify all cases in this set without
   looking at label_to_block for every case label.  */

struct case_bit_test
{
  wide_int mask;
  basic_block target_bb;
  tree label;
  int bits;

  /* Comparison function for qsort to order bit tests by decreasing
     probability of execution.  */
  static int cmp (const void *p1, const void *p2);
};

struct switch_decision_tree
{
  /* Constructor.  */
  switch_decision_tree (gswitch *swtch): m_switch (swtch), m_phi_mapping (),
    m_case_bbs (), m_case_node_pool ("struct case_node pool"),
    m_case_list (NULL)
  {
  }

  /* Analyze switch statement and return true when the statement is expanded
     as decision tree.  */
  bool analyze_switch_statement ();

  /* Attempt to expand CLUSTERS as a decision tree.  Return true when
     expanded.  */
  bool try_switch_expansion (vec<cluster *> &clusters);
  /* Compute the number of case labels that correspond to each outgoing edge of
     switch statement.  Record this information in the aux field of the edge.
     */
  void compute_cases_per_edge ();

  /* Before switch transformation, record all SSA_NAMEs defined in switch BB
     and used in a label basic block.  */
  void record_phi_operand_mapping ();

  /* Append new operands to PHI statements that were introduced due to
     addition of new edges to case labels.  */
  void fix_phi_operands_for_edges ();

  /* Generate a decision tree, switching on INDEX_EXPR and jumping to
     one of the labels in CASE_LIST or to the DEFAULT_LABEL.

     We generate a binary decision tree to select the appropriate target
     code.  */
  void emit (basic_block bb, tree index_expr,
	     profile_probability default_prob, tree index_type);

  /* Emit step-by-step code to select a case for the value of INDEX.
     The thus generated decision tree follows the form of the
     case-node binary tree NODE, whose nodes represent test conditions.
     DEFAULT_PROB is probability of cases leading to default BB.
     INDEX_TYPE is the type of the index of the switch.  */
  basic_block emit_case_nodes (basic_block bb, tree index,
			       case_tree_node *node,
			       profile_probability default_prob,
			       tree index_type, location_t);

  /* Take an ordered list of case nodes
     and transform them into a near optimal binary tree,
     on the assumption that any target code selection value is as
     likely as any other.

     The transformation is performed by splitting the ordered
     list into two equal sections plus a pivot.  The parts are
     then attached to the pivot as left and right branches.  Each
     branch is then transformed recursively.  */
  static void balance_case_nodes (case_tree_node **head,
				  case_tree_node *parent);

  /* Dump ROOT, a list or tree of case nodes, to file F.  */
  static void dump_case_nodes (FILE *f, case_tree_node *root, int indent_step,
			       int indent_level);

  /* Add an unconditional jump to CASE_BB that happens in basic block BB.  */
  static void emit_jump (basic_block bb, basic_block case_bb);

  /* Generate code to compare OP0 with OP1 so that the condition codes are
     set and to jump to LABEL_BB if the condition is true.
     COMPARISON is the GIMPLE comparison (EQ, NE, GT, etc.).
     PROB is the probability of jumping to LABEL_BB.  */
  static basic_block emit_cmp_and_jump_insns (basic_block bb, tree op0,
					      tree op1, tree_code comparison,
					      basic_block label_bb,
					      profile_probability prob,
					      location_t);

  /* Generate code to jump to LABEL if OP0 and OP1 are equal in mode MODE.
     PROB is the probability of jumping to LABEL_BB.  */
  static basic_block do_jump_if_equal (basic_block bb, tree op0, tree op1,
				       basic_block label_bb,
				       profile_probability prob,
				       location_t);

  /* Reset the aux field of all outgoing edges of switch basic block.  */
  static inline void reset_out_edges_aux (gswitch *swtch);

  /* Switch statement.  */
  gswitch *m_switch;

  /* Map of PHI nodes that have to be fixed after expansion.  */
  hash_map<tree, tree> m_phi_mapping;

  /* List of basic blocks that belong to labels of the switch.  */
  auto_vec<basic_block> m_case_bbs;

  /* Basic block with default label.  */
  basic_block m_default_bb;

  /* A pool for case nodes.  */
  object_allocator<case_tree_node> m_case_node_pool;

  /* Balanced tree of case nodes.  */
  case_tree_node *m_case_list;
};

/*
     Switch initialization conversion

The following pass changes simple initializations of scalars in a switch
statement into initializations from a static array.  Obviously, the values
must be constant and known at compile time and a default branch must be
provided.  For example, the following code:

	int a,b;

	switch (argc)
	{
	 case 1:
	 case 2:
		a_1 = 8;
		b_1 = 6;
		break;
	 case 3:
		a_2 = 9;
		b_2 = 5;
		break;
	 case 12:
		a_3 = 10;
		b_3 = 4;
		break;
	 default:
		a_4 = 16;
		b_4 = 1;
		break;
	}
	a_5 = PHI <a_1, a_2, a_3, a_4>
	b_5 = PHI <b_1, b_2, b_3, b_4>


is changed into:

	static const int = CSWTCH01[] = {6, 6, 5, 1, 1, 1, 1, 1, 1, 1, 1, 4};
	static const int = CSWTCH02[] = {8, 8, 9, 16, 16, 16, 16, 16, 16, 16,
				 16, 16, 10};

	if (((unsigned) argc) - 1 < 11)
	  {
	    a_6 = CSWTCH02[argc - 1];
	    b_6 = CSWTCH01[argc - 1];
	  }
	else
	  {
	    a_7 = 16;
	    b_7 = 1;
	  }
	a_5 = PHI <a_6, a_7>
	b_b = PHI <b_6, b_7>

There are further constraints.  Specifically, the range of values across all
case labels must not be bigger than SWITCH_CONVERSION_BRANCH_RATIO (default
eight) times the number of the actual switch branches.

This transformation was contributed by Martin Jambor, see this e-mail:
   http://gcc.gnu.org/ml/gcc-patches/2008-07/msg00011.html  */

/* The main structure of the pass.  */
struct switch_conversion
{
  /* Constructor.  */
  switch_conversion ();

  /* Destructor.  */
  ~switch_conversion ();

  /* The following function is invoked on every switch statement (the current
     one is given in SWTCH) and runs the individual phases of switch
     conversion on it one after another until one fails or the conversion
     is completed.  On success, NULL is in m_reason, otherwise points
     to a string with the reason why the conversion failed.  */
  void expand (gswitch *swtch);

  /* Collection information about SWTCH statement.  */
  void collect (gswitch *swtch);

  /* Checks whether the range given by individual case statements of the switch
     switch statement isn't too big and whether the number of branches actually
     satisfies the size of the new array.  */
  bool check_range ();

  /* Checks whether all but the final BB basic blocks are empty.  */
  bool check_all_empty_except_final ();

  /* This function checks whether all required values in phi nodes in final_bb
     are constants.  Required values are those that correspond to a basic block
     which is a part of the examined switch statement.  It returns true if the
     phi nodes are OK, otherwise false.  */
  bool check_final_bb ();

  /* The following function allocates default_values, target_{in,out}_names and
     constructors arrays.  The last one is also populated with pointers to
     vectors that will become constructors of new arrays.  */
  void create_temp_arrays ();

  /* Populate the array of default values in the order of phi nodes.
     DEFAULT_CASE is the CASE_LABEL_EXPR for the default switch branch
     if the range is non-contiguous or the default case has standard
     structure, otherwise it is the first non-default case instead.  */
  void gather_default_values (tree default_case);

  /* The following function populates the vectors in the constructors array with
     future contents of the static arrays.  The vectors are populated in the
     order of phi nodes.  */
  void build_constructors ();

  /* If all values in the constructor vector are products of a linear function
     a * x + b, then return true.  When true, COEFF_A and COEFF_B and
     coefficients of the linear function.  Note that equal values are special
     case of a linear function with a and b equal to zero.  */
  bool contains_linear_function_p (vec<constructor_elt, va_gc> *vec,
				   wide_int *coeff_a, wide_int *coeff_b);

  /* Return type which should be used for array elements, either TYPE's
     main variant or, for integral types, some smaller integral type
     that can still hold all the constants.  */
  tree array_value_type (tree type, int num);

  /* Create an appropriate array type and declaration and assemble a static
     array variable.  Also create a load statement that initializes
     the variable in question with a value from the static array.  SWTCH is
     the switch statement being converted, NUM is the index to
     arrays of constructors, default values and target SSA names
     for this particular array.  ARR_INDEX_TYPE is the type of the index
     of the new array, PHI is the phi node of the final BB that corresponds
     to the value that will be loaded from the created array.  TIDX
     is an ssa name of a temporary variable holding the index for loads from the
     new array.  */
  void build_one_array (int num, tree arr_index_type,
			gphi *phi, tree tidx);

  /* Builds and initializes static arrays initialized with values gathered from
     the switch statement.  Also creates statements that load values from
     them.  */
  void build_arrays ();

  /* Generates and appropriately inserts loads of default values at the position
     given by GSI.  Returns the last inserted statement.  */
  gassign *gen_def_assigns (gimple_stmt_iterator *gsi);

  /* Deletes the unused bbs and edges that now contain the switch statement and
     its empty branch bbs.  BBD is the now dead BB containing
     the original switch statement, FINAL is the last BB of the converted
     switch statement (in terms of succession).  */
  void prune_bbs (basic_block bbd, basic_block final, basic_block default_bb);

  /* Add values to phi nodes in final_bb for the two new edges.  E1F is the edge
     from the basic block loading values from an array and E2F from the basic
     block loading default values.  BBF is the last switch basic block (see the
     bbf description in the comment below).  */
  void fix_phi_nodes (edge e1f, edge e2f, basic_block bbf);

  /* Creates a check whether the switch expression value actually falls into the
     range given by all the cases.  If it does not, the temporaries are loaded
     with default values instead.  */
  void gen_inbound_check ();

  /* Switch statement for which switch conversion takes place.  */
  gswitch *m_switch;

  /* The expression used to decide the switch branch.  */
  tree m_index_expr;

  /* The following integer constants store the minimum and maximum value
     covered by the case labels.  */
  tree m_range_min;
  tree m_range_max;

  /* The difference between the above two numbers.  Stored here because it
     is used in all the conversion heuristics, as well as for some of the
     transformation, and it is expensive to re-compute it all the time.  */
  tree m_range_size;

  /* Basic block that contains the actual GIMPLE_SWITCH.  */
  basic_block m_switch_bb;

  /* Basic block that is the target of the default case.  */
  basic_block m_default_bb;

  /* The single successor block of all branches out of the GIMPLE_SWITCH,
     if such a block exists.  Otherwise NULL.  */
  basic_block m_final_bb;

  /* The probability of the default edge in the replaced switch.  */
  profile_probability m_default_prob;

  /* The count of the default edge in the replaced switch.  */
  profile_count m_default_count;

  /* Combined count of all other (non-default) edges in the replaced switch.  */
  profile_count m_other_count;

  /* Number of phi nodes in the final bb (that we'll be replacing).  */
  int m_phi_count;

  /* Constructors of new static arrays.  */
  vec<constructor_elt, va_gc> **m_constructors;

  /* Array of default values, in the same order as phi nodes.  */
  tree *m_default_values;

  /* Array of ssa names that are initialized with a value from a new static
     array.  */
  tree *m_target_inbound_names;

  /* Array of ssa names that are initialized with the default value if the
     switch expression is out of range.  */
  tree *m_target_outbound_names;

  /* VOP SSA_NAME.  */
  tree m_target_vop;

  /* The first load statement that loads a temporary from a new static array.
   */
  gimple *m_arr_ref_first;

  /* The last load statement that loads a temporary from a new static array.  */
  gimple *m_arr_ref_last;

  /* String reason why the case wasn't a good candidate that is written to the
     dump file, if there is one.  */
  const char *m_reason;

  /* True if default case is not used for any value between range_min and
     range_max inclusive.  */
  bool m_contiguous_range;

  /* True if default case does not have the required shape for other case
     labels.  */
  bool m_default_case_nonstandard;

  /* Number of uniq labels for non-default edges.  */
  unsigned int m_uniq;

  /* Count is number of non-default edges.  */
  unsigned int m_count;

  /* True if CFG has been changed.  */
  bool m_cfg_altered;
};

void
switch_decision_tree::reset_out_edges_aux (gswitch *swtch)
{
  basic_block bb = gimple_bb (swtch);
  edge e;
  edge_iterator ei;
  FOR_EACH_EDGE (e, ei, bb->succs)
    e->aux = (void *) 0;
}

} // tree_switch_conversion namespace

#endif // TREE_SWITCH_CONVERSION_H
