/* Header file for SSA dominator optimizations.
   Copyright (C) 2013-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/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "function.h"
#include "basic-block.h"
#include "tree.h"
#include "gimple.h"
#include "tree-pass.h"
#include "tree-pretty-print.h"
#include "tree-ssa-scopedtables.h"
#include "tree-ssa-threadedge.h"
#include "stor-layout.h"
#include "fold-const.h"
#include "tree-eh.h"
#include "internal-fn.h"
#include "tree-dfa.h"
#include "options.h"
#include "params.h"

static bool hashable_expr_equal_p (const struct hashable_expr *,
				   const struct hashable_expr *);

/* Initialize local stacks for this optimizer and record equivalences
   upon entry to BB.  Equivalences can come from the edge traversed to
   reach BB or they may come from PHI nodes at the start of BB.  */

/* Pop items off the unwinding stack, removing each from the hash table
   until a marker is encountered.  */

void
avail_exprs_stack::pop_to_marker ()
{
  /* Remove all the expressions made available in this block.  */
  while (m_stack.length () > 0)
    {
      std::pair<expr_hash_elt_t, expr_hash_elt_t> victim = m_stack.pop ();
      expr_hash_elt **slot;

      if (victim.first == NULL)
	break;

      /* This must precede the actual removal from the hash table,
         as ELEMENT and the table entry may share a call argument
         vector which will be freed during removal.  */
      if (dump_file && (dump_flags & TDF_DETAILS))
        {
          fprintf (dump_file, "<<<< ");
	  victim.first->print (dump_file);
        }

      slot = m_avail_exprs->find_slot (victim.first, NO_INSERT);
      gcc_assert (slot && *slot == victim.first);
      if (victim.second != NULL)
	{
	  delete *slot;
	  *slot = victim.second;
	}
      else
	m_avail_exprs->clear_slot (slot);
    }
}

/* Add <ELT1,ELT2> to the unwinding stack so they can be later removed
   from the hash table.  */

void
avail_exprs_stack::record_expr (class expr_hash_elt *elt1,
				class expr_hash_elt *elt2,
				char type)
{
  if (elt1 && dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "%c>>> ", type);
      elt1->print (dump_file);
    }

  m_stack.safe_push (std::pair<expr_hash_elt_t, expr_hash_elt_t> (elt1, elt2));
}

/* Helper for walk_non_aliased_vuses.  Determine if we arrived at
   the desired memory state.  */

static void *
vuse_eq (ao_ref *, tree vuse1, void *data)
{
  tree vuse2 = (tree) data;
  if (vuse1 == vuse2)
    return data;

  return NULL;
}

/* We looked for STMT in the hash table, but did not find it.

   If STMT is an assignment from a binary operator, we may know something
   about the operands relationship to each other which would allow
   us to derive a constant value for the RHS of STMT.  */

tree
avail_exprs_stack::simplify_binary_operation (gimple *stmt,
					      class expr_hash_elt element)
{
  if (is_gimple_assign (stmt))
    {
      struct hashable_expr *expr = element.expr ();
      if (expr->kind == EXPR_BINARY)
	{
	  enum tree_code code = expr->ops.binary.op;

	  switch (code)
	    {
	    /* For these cases, if we know the operands
	       are equal, then we know the result.  */
	    case MIN_EXPR:
	    case MAX_EXPR:
	    case BIT_IOR_EXPR:
	    case BIT_AND_EXPR:
	    case BIT_XOR_EXPR:
	    case MINUS_EXPR:
	    case TRUNC_DIV_EXPR:
	    case CEIL_DIV_EXPR:
	    case FLOOR_DIV_EXPR:
	    case ROUND_DIV_EXPR:
	    case EXACT_DIV_EXPR:
	    case TRUNC_MOD_EXPR:
	    case CEIL_MOD_EXPR:
	    case FLOOR_MOD_EXPR:
	    case ROUND_MOD_EXPR:
	      {
		/* Build a simple equality expr and query the hash table
		   for it.  */
		struct hashable_expr expr;
		expr.type = boolean_type_node;
		expr.kind = EXPR_BINARY;
		expr.ops.binary.op = EQ_EXPR;
		expr.ops.binary.opnd0 = gimple_assign_rhs1 (stmt);
		expr.ops.binary.opnd1 = gimple_assign_rhs2 (stmt);
		class expr_hash_elt element2 (&expr, NULL_TREE);
		expr_hash_elt **slot
		  = m_avail_exprs->find_slot (&element2, NO_INSERT);
		tree result_type = TREE_TYPE (gimple_assign_lhs (stmt));

		/* If the query was successful and returned a nonzero
		   result, then we know that the operands of the binary
		   expression are the same.  In many cases this allows
		   us to compute a constant result of the expression
		   at compile time, even if we do not know the exact
		   values of the operands.  */
		if (slot && *slot && integer_onep ((*slot)->lhs ()))
		  {
		    switch (code)
		      {
		      case MIN_EXPR:
		      case MAX_EXPR:
		      case BIT_IOR_EXPR:
		      case BIT_AND_EXPR:
			return gimple_assign_rhs1 (stmt);

		      case MINUS_EXPR:
			/* This is unsafe for certain floats even in non-IEEE
			   formats.  In IEEE, it is unsafe because it does
			   wrong for NaNs.  */
			if (FLOAT_TYPE_P (result_type)
			    && HONOR_NANS (result_type))
			  break;
			/* FALLTHRU */
		      case BIT_XOR_EXPR:
		      case TRUNC_MOD_EXPR:
		      case CEIL_MOD_EXPR:
		      case FLOOR_MOD_EXPR:
		      case ROUND_MOD_EXPR:
			return build_zero_cst (result_type);

		      case TRUNC_DIV_EXPR:
		      case CEIL_DIV_EXPR:
		      case FLOOR_DIV_EXPR:
		      case ROUND_DIV_EXPR:
		      case EXACT_DIV_EXPR:
			/* Avoid _Fract types where we can't build 1.  */
			if (ALL_FRACT_MODE_P (TYPE_MODE (result_type)))
			  break;
			return build_one_cst (result_type);

		      default:
			gcc_unreachable ();
		      }
		  }
		break;
	      }

	    default:
	      break;
	    }
	}
    }
  return NULL_TREE;
}

/* Search for an existing instance of STMT in the AVAIL_EXPRS_STACK table.
   If found, return its LHS. Otherwise insert STMT in the table and
   return NULL_TREE.

   Also, when an expression is first inserted in the  table, it is also
   is also added to AVAIL_EXPRS_STACK, so that it can be removed when
   we finish processing this block and its children.  */

tree
avail_exprs_stack::lookup_avail_expr (gimple *stmt, bool insert, bool tbaa_p)
{
  expr_hash_elt **slot;
  tree lhs;

  /* Get LHS of phi, assignment, or call; else NULL_TREE.  */
  if (gimple_code (stmt) == GIMPLE_PHI)
    lhs = gimple_phi_result (stmt);
  else
    lhs = gimple_get_lhs (stmt);

  class expr_hash_elt element (stmt, lhs);

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "LKUP ");
      element.print (dump_file);
    }

  /* Don't bother remembering constant assignments and copy operations.
     Constants and copy operations are handled by the constant/copy propagator
     in optimize_stmt.  */
  if (element.expr()->kind == EXPR_SINGLE
      && (TREE_CODE (element.expr()->ops.single.rhs) == SSA_NAME
          || is_gimple_min_invariant (element.expr()->ops.single.rhs)))
    return NULL_TREE;

  /* Finally try to find the expression in the main expression hash table.  */
  slot = m_avail_exprs->find_slot (&element, (insert ? INSERT : NO_INSERT));
  if (slot == NULL)
    {
      return NULL_TREE;
    }
  else if (*slot == NULL)
    {
      /* If we did not find the expression in the hash table, we may still
	 be able to produce a result for some expressions.  */
      tree retval = avail_exprs_stack::simplify_binary_operation (stmt,
								  element);

      /* We have, in effect, allocated *SLOT for ELEMENT at this point.
	 We must initialize *SLOT to a real entry, even if we found a
	 way to prove ELEMENT was a constant after not finding ELEMENT
	 in the hash table.

	 An uninitialized or empty slot is an indication no prior objects
	 entered into the hash table had a hash collection with ELEMENT.

	 If we fail to do so and had such entries in the table, they
	 would become unreachable.  */
      class expr_hash_elt *element2 = new expr_hash_elt (element);
      *slot = element2;

      record_expr (element2, NULL, '2');
      return retval;
    }

  /* If we found a redundant memory operation do an alias walk to
     check if we can re-use it.  */
  if (gimple_vuse (stmt) != (*slot)->vop ())
    {
      tree vuse1 = (*slot)->vop ();
      tree vuse2 = gimple_vuse (stmt);
      /* If we have a load of a register and a candidate in the
	 hash with vuse1 then try to reach its stmt by walking
	 up the virtual use-def chain using walk_non_aliased_vuses.
	 But don't do this when removing expressions from the hash.  */
      ao_ref ref;
      unsigned limit = PARAM_VALUE (PARAM_SCCVN_MAX_ALIAS_QUERIES_PER_ACCESS);
      if (!(vuse1 && vuse2
	    && gimple_assign_single_p (stmt)
	    && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME
	    && (ao_ref_init (&ref, gimple_assign_rhs1 (stmt)),
		ref.base_alias_set = ref.ref_alias_set = tbaa_p ? -1 : 0, true)
	    && walk_non_aliased_vuses (&ref, vuse2, true, vuse_eq, NULL, NULL,
				       limit, vuse1) != NULL))
	{
	  if (insert)
	    {
	      class expr_hash_elt *element2 = new expr_hash_elt (element);

	      /* Insert the expr into the hash by replacing the current
		 entry and recording the value to restore in the
		 avail_exprs_stack.  */
	      record_expr (element2, *slot, '2');
	      *slot = element2;
	    }
	  return NULL_TREE;
	}
    }

  /* Extract the LHS of the assignment so that it can be used as the current
     definition of another variable.  */
  lhs = (*slot)->lhs ();

  /* Valueize the result.  */
  if (TREE_CODE (lhs) == SSA_NAME)
    {
      tree tem = SSA_NAME_VALUE (lhs);
      if (tem)
	lhs = tem;
    }

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "FIND: ");
      print_generic_expr (dump_file, lhs);
      fprintf (dump_file, "\n");
    }

  return lhs;
}

/* Enter condition equivalence P into the hash table.

   This indicates that a conditional expression has a known
   boolean value.  */

void
avail_exprs_stack::record_cond (cond_equivalence *p)
{
  class expr_hash_elt *element = new expr_hash_elt (&p->cond, p->value);
  expr_hash_elt **slot;

  slot = m_avail_exprs->find_slot_with_hash (element, element->hash (), INSERT);
  if (*slot == NULL)
    {
      *slot = element;
      record_expr (element, NULL, '1');
    }
  else
    delete element;
}

/* Generate a hash value for a pair of expressions.  This can be used
   iteratively by passing a previous result in HSTATE.

   The same hash value is always returned for a given pair of expressions,
   regardless of the order in which they are presented.  This is useful in
   hashing the operands of commutative functions.  */

namespace inchash
{

static void
add_expr_commutative (const_tree t1, const_tree t2, hash &hstate)
{
  hash one, two;

  inchash::add_expr (t1, one);
  inchash::add_expr (t2, two);
  hstate.add_commutative (one, two);
}

/* Compute a hash value for a hashable_expr value EXPR and a
   previously accumulated hash value VAL.  If two hashable_expr
   values compare equal with hashable_expr_equal_p, they must
   hash to the same value, given an identical value of VAL.
   The logic is intended to follow inchash::add_expr in tree.c.  */

static void
add_hashable_expr (const struct hashable_expr *expr, hash &hstate)
{
  switch (expr->kind)
    {
    case EXPR_SINGLE:
      inchash::add_expr (expr->ops.single.rhs, hstate);
      break;

    case EXPR_UNARY:
      hstate.add_object (expr->ops.unary.op);

      /* Make sure to include signedness in the hash computation.
         Don't hash the type, that can lead to having nodes which
         compare equal according to operand_equal_p, but which
         have different hash codes.  */
      if (CONVERT_EXPR_CODE_P (expr->ops.unary.op)
          || expr->ops.unary.op == NON_LVALUE_EXPR)
        hstate.add_int (TYPE_UNSIGNED (expr->type));

      inchash::add_expr (expr->ops.unary.opnd, hstate);
      break;

    case EXPR_BINARY:
      hstate.add_object (expr->ops.binary.op);
      if (commutative_tree_code (expr->ops.binary.op))
	inchash::add_expr_commutative (expr->ops.binary.opnd0,
					  expr->ops.binary.opnd1, hstate);
      else
        {
          inchash::add_expr (expr->ops.binary.opnd0, hstate);
          inchash::add_expr (expr->ops.binary.opnd1, hstate);
        }
      break;

    case EXPR_TERNARY:
      hstate.add_object (expr->ops.ternary.op);
      if (commutative_ternary_tree_code (expr->ops.ternary.op))
	inchash::add_expr_commutative (expr->ops.ternary.opnd0,
					  expr->ops.ternary.opnd1, hstate);
      else
        {
          inchash::add_expr (expr->ops.ternary.opnd0, hstate);
          inchash::add_expr (expr->ops.ternary.opnd1, hstate);
        }
      inchash::add_expr (expr->ops.ternary.opnd2, hstate);
      break;

    case EXPR_CALL:
      {
        size_t i;
        enum tree_code code = CALL_EXPR;
        gcall *fn_from;

        hstate.add_object (code);
        fn_from = expr->ops.call.fn_from;
        if (gimple_call_internal_p (fn_from))
          hstate.merge_hash ((hashval_t) gimple_call_internal_fn (fn_from));
        else
          inchash::add_expr (gimple_call_fn (fn_from), hstate);
        for (i = 0; i < expr->ops.call.nargs; i++)
          inchash::add_expr (expr->ops.call.args[i], hstate);
      }
      break;

    case EXPR_PHI:
      {
        size_t i;

        for (i = 0; i < expr->ops.phi.nargs; i++)
          inchash::add_expr (expr->ops.phi.args[i], hstate);
      }
      break;

    default:
      gcc_unreachable ();
    }
}

}

/* Hashing and equality functions.  We compute a value number for expressions
   using the code of the expression and the SSA numbers of its operands.  */

static hashval_t
avail_expr_hash (class expr_hash_elt *p)
{
  const struct hashable_expr *expr = p->expr ();
  inchash::hash hstate;

  if (expr->kind == EXPR_SINGLE)
    {
      /* T could potentially be a switch index or a goto dest.  */
      tree t = expr->ops.single.rhs;
      if (TREE_CODE (t) == MEM_REF || handled_component_p (t))
	{
	  /* Make equivalent statements of both these kinds hash together.
	     Dealing with both MEM_REF and ARRAY_REF allows us not to care
	     about equivalence with other statements not considered here.  */
	  bool reverse;
	  poly_int64 offset, size, max_size;
	  tree base = get_ref_base_and_extent (t, &offset, &size, &max_size,
					       &reverse);
	  /* Strictly, we could try to normalize variable-sized accesses too,
	    but here we just deal with the common case.  */
	  if (known_size_p (max_size)
	      && known_eq (size, max_size))
	    {
	      enum tree_code code = MEM_REF;
	      hstate.add_object (code);
	      inchash::add_expr (base, hstate);
	      hstate.add_object (offset);
	      hstate.add_object (size);
	      return hstate.end ();
	    }
	}
    }

  inchash::add_hashable_expr (expr, hstate);

  return hstate.end ();
}

/* Compares trees T0 and T1 to see if they are MEM_REF or ARRAY_REFs equivalent
   to each other.  (That is, they return the value of the same bit of memory.)

   Return TRUE if the two are so equivalent; FALSE if not (which could still
   mean the two are equivalent by other means).  */

static bool
equal_mem_array_ref_p (tree t0, tree t1)
{
  if (TREE_CODE (t0) != MEM_REF && ! handled_component_p (t0))
    return false;
  if (TREE_CODE (t1) != MEM_REF && ! handled_component_p (t1))
    return false;

  if (!types_compatible_p (TREE_TYPE (t0), TREE_TYPE (t1)))
    return false;
  bool rev0;
  poly_int64 off0, sz0, max0;
  tree base0 = get_ref_base_and_extent (t0, &off0, &sz0, &max0, &rev0);
  if (!known_size_p (max0)
      || maybe_ne (sz0, max0))
    return false;

  bool rev1;
  poly_int64 off1, sz1, max1;
  tree base1 = get_ref_base_and_extent (t1, &off1, &sz1, &max1, &rev1);
  if (!known_size_p (max1)
      || maybe_ne (sz1, max1))
    return false;

  if (rev0 != rev1 || maybe_ne (sz0, sz1) || maybe_ne (off0, off1))
    return false;

  return operand_equal_p (base0, base1, 0);
}

/* Compare two hashable_expr structures for equivalence.  They are
   considered equivalent when the expressions they denote must
   necessarily be equal.  The logic is intended to follow that of
   operand_equal_p in fold-const.c */

static bool
hashable_expr_equal_p (const struct hashable_expr *expr0,
		       const struct hashable_expr *expr1)
{
  tree type0 = expr0->type;
  tree type1 = expr1->type;

  /* If either type is NULL, there is nothing to check.  */
  if ((type0 == NULL_TREE) ^ (type1 == NULL_TREE))
    return false;

  /* If both types don't have the same signedness, precision, and mode,
     then we can't consider  them equal.  */
  if (type0 != type1
      && (TREE_CODE (type0) == ERROR_MARK
	  || TREE_CODE (type1) == ERROR_MARK
	  || TYPE_UNSIGNED (type0) != TYPE_UNSIGNED (type1)
	  || TYPE_PRECISION (type0) != TYPE_PRECISION (type1)
	  || TYPE_MODE (type0) != TYPE_MODE (type1)))
    return false;

  if (expr0->kind != expr1->kind)
    return false;

  switch (expr0->kind)
    {
    case EXPR_SINGLE:
      return equal_mem_array_ref_p (expr0->ops.single.rhs,
				    expr1->ops.single.rhs)
	     || operand_equal_p (expr0->ops.single.rhs,
				 expr1->ops.single.rhs, 0);
    case EXPR_UNARY:
      if (expr0->ops.unary.op != expr1->ops.unary.op)
        return false;

      if ((CONVERT_EXPR_CODE_P (expr0->ops.unary.op)
           || expr0->ops.unary.op == NON_LVALUE_EXPR)
          && TYPE_UNSIGNED (expr0->type) != TYPE_UNSIGNED (expr1->type))
        return false;

      return operand_equal_p (expr0->ops.unary.opnd,
                              expr1->ops.unary.opnd, 0);

    case EXPR_BINARY:
      if (expr0->ops.binary.op != expr1->ops.binary.op)
	return false;

      if (operand_equal_p (expr0->ops.binary.opnd0,
			   expr1->ops.binary.opnd0, 0)
	  && operand_equal_p (expr0->ops.binary.opnd1,
			      expr1->ops.binary.opnd1, 0))
	return true;

      /* For commutative ops, allow the other order.  */
      return (commutative_tree_code (expr0->ops.binary.op)
	      && operand_equal_p (expr0->ops.binary.opnd0,
				  expr1->ops.binary.opnd1, 0)
	      && operand_equal_p (expr0->ops.binary.opnd1,
				  expr1->ops.binary.opnd0, 0));

    case EXPR_TERNARY:
      if (expr0->ops.ternary.op != expr1->ops.ternary.op
	  || !operand_equal_p (expr0->ops.ternary.opnd2,
			       expr1->ops.ternary.opnd2, 0))
	return false;

      /* BIT_INSERT_EXPR has an implict operand as the type precision
         of op1.  Need to check to make sure they are the same.  */
      if (expr0->ops.ternary.op == BIT_INSERT_EXPR
	  && TREE_CODE (expr0->ops.ternary.opnd1) == INTEGER_CST
          && TREE_CODE (expr1->ops.ternary.opnd1) == INTEGER_CST
          && TYPE_PRECISION (TREE_TYPE (expr0->ops.ternary.opnd1))
              != TYPE_PRECISION (TREE_TYPE (expr1->ops.ternary.opnd1)))
        return false;

      if (operand_equal_p (expr0->ops.ternary.opnd0,
			   expr1->ops.ternary.opnd0, 0)
	  && operand_equal_p (expr0->ops.ternary.opnd1,
			      expr1->ops.ternary.opnd1, 0))
	return true;

      /* For commutative ops, allow the other order.  */
      return (commutative_ternary_tree_code (expr0->ops.ternary.op)
	      && operand_equal_p (expr0->ops.ternary.opnd0,
				  expr1->ops.ternary.opnd1, 0)
	      && operand_equal_p (expr0->ops.ternary.opnd1,
				  expr1->ops.ternary.opnd0, 0));

    case EXPR_CALL:
      {
        size_t i;

        /* If the calls are to different functions, then they
           clearly cannot be equal.  */
        if (!gimple_call_same_target_p (expr0->ops.call.fn_from,
                                        expr1->ops.call.fn_from))
          return false;

        if (! expr0->ops.call.pure)
          return false;

        if (expr0->ops.call.nargs !=  expr1->ops.call.nargs)
          return false;

        for (i = 0; i < expr0->ops.call.nargs; i++)
          if (! operand_equal_p (expr0->ops.call.args[i],
                                 expr1->ops.call.args[i], 0))
            return false;

	if (stmt_could_throw_p (cfun, expr0->ops.call.fn_from))
	  {
	    int lp0 = lookup_stmt_eh_lp (expr0->ops.call.fn_from);
	    int lp1 = lookup_stmt_eh_lp (expr1->ops.call.fn_from);
	    if ((lp0 > 0 || lp1 > 0) && lp0 != lp1)
	      return false;
	  }

        return true;
      }

    case EXPR_PHI:
      {
        size_t i;

        if (expr0->ops.phi.nargs !=  expr1->ops.phi.nargs)
          return false;

        for (i = 0; i < expr0->ops.phi.nargs; i++)
          if (! operand_equal_p (expr0->ops.phi.args[i],
                                 expr1->ops.phi.args[i], 0))
            return false;

        return true;
      }

    default:
      gcc_unreachable ();
    }
}

/* Given a statement STMT, construct a hash table element.  */

expr_hash_elt::expr_hash_elt (gimple *stmt, tree orig_lhs)
{
  enum gimple_code code = gimple_code (stmt);
  struct hashable_expr *expr = this->expr ();

  if (code == GIMPLE_ASSIGN)
    {
      enum tree_code subcode = gimple_assign_rhs_code (stmt);

      switch (get_gimple_rhs_class (subcode))
        {
        case GIMPLE_SINGLE_RHS:
	  expr->kind = EXPR_SINGLE;
	  expr->type = TREE_TYPE (gimple_assign_rhs1 (stmt));
	  expr->ops.single.rhs = gimple_assign_rhs1 (stmt);
	  break;
        case GIMPLE_UNARY_RHS:
	  expr->kind = EXPR_UNARY;
	  expr->type = TREE_TYPE (gimple_assign_lhs (stmt));
	  if (CONVERT_EXPR_CODE_P (subcode))
	    subcode = NOP_EXPR;
	  expr->ops.unary.op = subcode;
	  expr->ops.unary.opnd = gimple_assign_rhs1 (stmt);
	  break;
        case GIMPLE_BINARY_RHS:
	  expr->kind = EXPR_BINARY;
	  expr->type = TREE_TYPE (gimple_assign_lhs (stmt));
	  expr->ops.binary.op = subcode;
	  expr->ops.binary.opnd0 = gimple_assign_rhs1 (stmt);
	  expr->ops.binary.opnd1 = gimple_assign_rhs2 (stmt);
	  break;
        case GIMPLE_TERNARY_RHS:
	  expr->kind = EXPR_TERNARY;
	  expr->type = TREE_TYPE (gimple_assign_lhs (stmt));
	  expr->ops.ternary.op = subcode;
	  expr->ops.ternary.opnd0 = gimple_assign_rhs1 (stmt);
	  expr->ops.ternary.opnd1 = gimple_assign_rhs2 (stmt);
	  expr->ops.ternary.opnd2 = gimple_assign_rhs3 (stmt);
	  break;
        default:
          gcc_unreachable ();
        }
    }
  else if (code == GIMPLE_COND)
    {
      expr->type = boolean_type_node;
      expr->kind = EXPR_BINARY;
      expr->ops.binary.op = gimple_cond_code (stmt);
      expr->ops.binary.opnd0 = gimple_cond_lhs (stmt);
      expr->ops.binary.opnd1 = gimple_cond_rhs (stmt);
    }
  else if (gcall *call_stmt = dyn_cast <gcall *> (stmt))
    {
      size_t nargs = gimple_call_num_args (call_stmt);
      size_t i;

      gcc_assert (gimple_call_lhs (call_stmt));

      expr->type = TREE_TYPE (gimple_call_lhs (call_stmt));
      expr->kind = EXPR_CALL;
      expr->ops.call.fn_from = call_stmt;

      if (gimple_call_flags (call_stmt) & (ECF_CONST | ECF_PURE))
        expr->ops.call.pure = true;
      else
        expr->ops.call.pure = false;

      expr->ops.call.nargs = nargs;
      expr->ops.call.args = XCNEWVEC (tree, nargs);
      for (i = 0; i < nargs; i++)
        expr->ops.call.args[i] = gimple_call_arg (call_stmt, i);
    }
  else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt))
    {
      expr->type = TREE_TYPE (gimple_switch_index (swtch_stmt));
      expr->kind = EXPR_SINGLE;
      expr->ops.single.rhs = gimple_switch_index (swtch_stmt);
    }
  else if (code == GIMPLE_GOTO)
    {
      expr->type = TREE_TYPE (gimple_goto_dest (stmt));
      expr->kind = EXPR_SINGLE;
      expr->ops.single.rhs = gimple_goto_dest (stmt);
    }
  else if (code == GIMPLE_PHI)
    {
      size_t nargs = gimple_phi_num_args (stmt);
      size_t i;

      expr->type = TREE_TYPE (gimple_phi_result (stmt));
      expr->kind = EXPR_PHI;
      expr->ops.phi.nargs = nargs;
      expr->ops.phi.args = XCNEWVEC (tree, nargs);
      for (i = 0; i < nargs; i++)
        expr->ops.phi.args[i] = gimple_phi_arg_def (stmt, i);
    }
  else
    gcc_unreachable ();

  m_lhs = orig_lhs;
  m_vop = gimple_vuse (stmt);
  m_hash = avail_expr_hash (this);
  m_stamp = this;
}

/* Given a hashable_expr expression ORIG and an ORIG_LHS,
   construct a hash table element.  */

expr_hash_elt::expr_hash_elt (struct hashable_expr *orig, tree orig_lhs)
{
  m_expr = *orig;
  m_lhs = orig_lhs;
  m_vop = NULL_TREE;
  m_hash = avail_expr_hash (this);
  m_stamp = this;
}

/* Copy constructor for a hash table element.  */

expr_hash_elt::expr_hash_elt (class expr_hash_elt &old_elt)
{
  m_expr = old_elt.m_expr;
  m_lhs = old_elt.m_lhs;
  m_vop = old_elt.m_vop;
  m_hash = old_elt.m_hash;
  m_stamp = this;

  /* Now deep copy the malloc'd space for CALL and PHI args.  */
  if (old_elt.m_expr.kind == EXPR_CALL)
    {
      size_t nargs = old_elt.m_expr.ops.call.nargs;
      size_t i;

      m_expr.ops.call.args = XCNEWVEC (tree, nargs);
      for (i = 0; i < nargs; i++)
        m_expr.ops.call.args[i] = old_elt.m_expr.ops.call.args[i];
    }
  else if (old_elt.m_expr.kind == EXPR_PHI)
    {
      size_t nargs = old_elt.m_expr.ops.phi.nargs;
      size_t i;

      m_expr.ops.phi.args = XCNEWVEC (tree, nargs);
      for (i = 0; i < nargs; i++)
        m_expr.ops.phi.args[i] = old_elt.m_expr.ops.phi.args[i];
    }
}

/* Calls and PHIs have a variable number of arguments that are allocated
   on the heap.  Thus we have to have a special dtor to release them.  */

expr_hash_elt::~expr_hash_elt ()
{
  if (m_expr.kind == EXPR_CALL)
    free (m_expr.ops.call.args);
  else if (m_expr.kind == EXPR_PHI)
    free (m_expr.ops.phi.args);
}

/* Print a diagnostic dump of an expression hash table entry.  */

void
expr_hash_elt::print (FILE *stream)
{
  fprintf (stream, "STMT ");

  if (m_lhs)
    {
      print_generic_expr (stream, m_lhs);
      fprintf (stream, " = ");
    }

  switch (m_expr.kind)
    {
      case EXPR_SINGLE:
	print_generic_expr (stream, m_expr.ops.single.rhs);
	break;

      case EXPR_UNARY:
	fprintf (stream, "%s ", get_tree_code_name (m_expr.ops.unary.op));
	print_generic_expr (stream, m_expr.ops.unary.opnd);
	break;

      case EXPR_BINARY:
	print_generic_expr (stream, m_expr.ops.binary.opnd0);
	fprintf (stream, " %s ", get_tree_code_name (m_expr.ops.binary.op));
	print_generic_expr (stream, m_expr.ops.binary.opnd1);
	break;

      case EXPR_TERNARY:
	fprintf (stream, " %s <", get_tree_code_name (m_expr.ops.ternary.op));
	print_generic_expr (stream, m_expr.ops.ternary.opnd0);
	fputs (", ", stream);
	print_generic_expr (stream, m_expr.ops.ternary.opnd1);
	fputs (", ", stream);
	print_generic_expr (stream, m_expr.ops.ternary.opnd2);
	fputs (">", stream);
	break;

      case EXPR_CALL:
        {
          size_t i;
          size_t nargs = m_expr.ops.call.nargs;
          gcall *fn_from;

          fn_from = m_expr.ops.call.fn_from;
          if (gimple_call_internal_p (fn_from))
	    fprintf (stream, ".%s",
		     internal_fn_name (gimple_call_internal_fn (fn_from)));
          else
	    print_generic_expr (stream, gimple_call_fn (fn_from));
          fprintf (stream, " (");
          for (i = 0; i < nargs; i++)
            {
	      print_generic_expr (stream, m_expr.ops.call.args[i]);
              if (i + 1 < nargs)
                fprintf (stream, ", ");
            }
          fprintf (stream, ")");
        }
        break;

      case EXPR_PHI:
        {
          size_t i;
          size_t nargs = m_expr.ops.phi.nargs;

          fprintf (stream, "PHI <");
          for (i = 0; i < nargs; i++)
            {
	      print_generic_expr (stream, m_expr.ops.phi.args[i]);
              if (i + 1 < nargs)
                fprintf (stream, ", ");
            }
          fprintf (stream, ">");
        }
        break;
    }

  if (m_vop)
    {
      fprintf (stream, " with ");
      print_generic_expr (stream, m_vop);
    }

  fprintf (stream, "\n");
}

/* Pop entries off the stack until we hit the NULL marker.
   For each entry popped, use the SRC/DEST pair to restore
   SRC to its prior value.  */

void
const_and_copies::pop_to_marker (void)
{
  while (m_stack.length () > 0)
    {
      tree prev_value, dest;

      dest = m_stack.pop ();

      /* A NULL value indicates we should stop unwinding, otherwise
	 pop off the next entry as they're recorded in pairs.  */
      if (dest == NULL)
	break;

      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "<<<< COPY ");
	  print_generic_expr (dump_file, dest);
	  fprintf (dump_file, " = ");
	  print_generic_expr (dump_file, SSA_NAME_VALUE (dest));
	  fprintf (dump_file, "\n");
	}

      prev_value = m_stack.pop ();
      set_ssa_name_value (dest, prev_value);
    }
}

/* Record that X has the value Y and that X's previous value is PREV_X. 

   This variant does not follow the value chain for Y.  */

void
const_and_copies::record_const_or_copy_raw (tree x, tree y, tree prev_x)
{
  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "0>>> COPY ");
      print_generic_expr (dump_file, x);
      fprintf (dump_file, " = ");
      print_generic_expr (dump_file, y);
      fprintf (dump_file, "\n");
    }

  set_ssa_name_value (x, y);
  m_stack.reserve (2);
  m_stack.quick_push (prev_x);
  m_stack.quick_push (x);
}

/* Record that X has the value Y.  */

void
const_and_copies::record_const_or_copy (tree x, tree y)
{
  record_const_or_copy (x, y, SSA_NAME_VALUE (x));
}

/* Record that X has the value Y and that X's previous value is PREV_X. 

   This variant follow's Y value chain.  */

void
const_and_copies::record_const_or_copy (tree x, tree y, tree prev_x)
{
  /* Y may be NULL if we are invalidating entries in the table.  */
  if (y && TREE_CODE (y) == SSA_NAME)
    {
      tree tmp = SSA_NAME_VALUE (y);
      y = tmp ? tmp : y;
    }

  record_const_or_copy_raw (x, y, prev_x);
}

bool
expr_elt_hasher::equal (const value_type &p1, const compare_type &p2)
{
  const struct hashable_expr *expr1 = p1->expr ();
  const struct expr_hash_elt *stamp1 = p1->stamp ();
  const struct hashable_expr *expr2 = p2->expr ();
  const struct expr_hash_elt *stamp2 = p2->stamp ();

  /* This case should apply only when removing entries from the table.  */
  if (stamp1 == stamp2)
    return true;

  if (p1->hash () != p2->hash ())
    return false;

  /* In case of a collision, both RHS have to be identical and have the
     same VUSE operands.  */
  if (hashable_expr_equal_p (expr1, expr2)
      && types_compatible_p (expr1->type, expr2->type))
    return true;

  return false;
}

/* Given a conditional expression COND as a tree, initialize
   a hashable_expr expression EXPR.  The conditional must be a
   comparison or logical negation.  A constant or a variable is
   not permitted.  */

void
initialize_expr_from_cond (tree cond, struct hashable_expr *expr)
{
  expr->type = boolean_type_node;

  if (COMPARISON_CLASS_P (cond))
    {
      expr->kind = EXPR_BINARY;
      expr->ops.binary.op = TREE_CODE (cond);
      expr->ops.binary.opnd0 = TREE_OPERAND (cond, 0);
      expr->ops.binary.opnd1 = TREE_OPERAND (cond, 1);
    }
  else if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
    {
      expr->kind = EXPR_UNARY;
      expr->ops.unary.op = TRUTH_NOT_EXPR;
      expr->ops.unary.opnd = TREE_OPERAND (cond, 0);
    }
  else
    gcc_unreachable ();
}

/* Build a cond_equivalence record indicating that the comparison
   CODE holds between operands OP0 and OP1 and push it to **P.  */

static void
build_and_record_new_cond (enum tree_code code,
                           tree op0, tree op1,
                           vec<cond_equivalence> *p,
			   bool val = true)
{
  cond_equivalence c;
  struct hashable_expr *cond = &c.cond;

  gcc_assert (TREE_CODE_CLASS (code) == tcc_comparison);

  cond->type = boolean_type_node;
  cond->kind = EXPR_BINARY;
  cond->ops.binary.op = code;
  cond->ops.binary.opnd0 = op0;
  cond->ops.binary.opnd1 = op1;

  c.value = val ? boolean_true_node : boolean_false_node;
  p->safe_push (c);
}

/* Record that COND is true and INVERTED is false into the edge information
   structure.  Also record that any conditions dominated by COND are true
   as well.

   For example, if a < b is true, then a <= b must also be true.  */

void
record_conditions (vec<cond_equivalence> *p, tree cond, tree inverted)
{
  tree op0, op1;
  cond_equivalence c;

  if (!COMPARISON_CLASS_P (cond))
    return;

  op0 = TREE_OPERAND (cond, 0);
  op1 = TREE_OPERAND (cond, 1);

  switch (TREE_CODE (cond))
    {
    case LT_EXPR:
    case GT_EXPR:
      if (FLOAT_TYPE_P (TREE_TYPE (op0)))
	{
	  build_and_record_new_cond (ORDERED_EXPR, op0, op1, p);
	  build_and_record_new_cond (LTGT_EXPR, op0, op1, p);
	}

      build_and_record_new_cond ((TREE_CODE (cond) == LT_EXPR
				  ? LE_EXPR : GE_EXPR),
				 op0, op1, p);
      build_and_record_new_cond (NE_EXPR, op0, op1, p);
      build_and_record_new_cond (EQ_EXPR, op0, op1, p, false);
      break;

    case GE_EXPR:
    case LE_EXPR:
      if (FLOAT_TYPE_P (TREE_TYPE (op0)))
	{
	  build_and_record_new_cond (ORDERED_EXPR, op0, op1, p);
	}
      break;

    case EQ_EXPR:
      if (FLOAT_TYPE_P (TREE_TYPE (op0)))
	{
	  build_and_record_new_cond (ORDERED_EXPR, op0, op1, p);
	}
      build_and_record_new_cond (LE_EXPR, op0, op1, p);
      build_and_record_new_cond (GE_EXPR, op0, op1, p);
      break;

    case UNORDERED_EXPR:
      build_and_record_new_cond (NE_EXPR, op0, op1, p);
      build_and_record_new_cond (UNLE_EXPR, op0, op1, p);
      build_and_record_new_cond (UNGE_EXPR, op0, op1, p);
      build_and_record_new_cond (UNEQ_EXPR, op0, op1, p);
      build_and_record_new_cond (UNLT_EXPR, op0, op1, p);
      build_and_record_new_cond (UNGT_EXPR, op0, op1, p);
      break;

    case UNLT_EXPR:
    case UNGT_EXPR:
      build_and_record_new_cond ((TREE_CODE (cond) == UNLT_EXPR
				  ? UNLE_EXPR : UNGE_EXPR),
				 op0, op1, p);
      build_and_record_new_cond (NE_EXPR, op0, op1, p);
      break;

    case UNEQ_EXPR:
      build_and_record_new_cond (UNLE_EXPR, op0, op1, p);
      build_and_record_new_cond (UNGE_EXPR, op0, op1, p);
      break;

    case LTGT_EXPR:
      build_and_record_new_cond (NE_EXPR, op0, op1, p);
      build_and_record_new_cond (ORDERED_EXPR, op0, op1, p);
      break;

    default:
      break;
    }

  /* Now store the original true and false conditions into the first
     two slots.  */
  initialize_expr_from_cond (cond, &c.cond);
  c.value = boolean_true_node;
  p->safe_push (c);

  /* It is possible for INVERTED to be the negation of a comparison,
     and not a valid RHS or GIMPLE_COND condition.  This happens because
     invert_truthvalue may return such an expression when asked to invert
     a floating-point comparison.  These comparisons are not assumed to
     obey the trichotomy law.  */
  initialize_expr_from_cond (inverted, &c.cond);
  c.value = boolean_false_node;
  p->safe_push (c);
}
