/* Lower complex number operations to scalar operations.
   Copyright (C) 2004-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 "backend.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "cfghooks.h"
#include "tree-pass.h"
#include "ssa.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "tree-eh.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "gimplify-me.h"
#include "tree-cfg.h"
#include "tree-dfa.h"
#include "tree-ssa.h"
#include "tree-ssa-propagate.h"
#include "tree-hasher.h"
#include "cfgloop.h"
#include "cfganal.h"


/* For each complex ssa name, a lattice value.  We're interested in finding
   out whether a complex number is degenerate in some way, having only real
   or only complex parts.  */

enum
{
  UNINITIALIZED = 0,
  ONLY_REAL = 1,
  ONLY_IMAG = 2,
  VARYING = 3
};

/* The type complex_lattice_t holds combinations of the above
   constants.  */
typedef int complex_lattice_t;

#define PAIR(a, b)  ((a) << 2 | (b))

class complex_propagate : public ssa_propagation_engine
{
  enum ssa_prop_result visit_stmt (gimple *, edge *, tree *) FINAL OVERRIDE;
  enum ssa_prop_result visit_phi (gphi *) FINAL OVERRIDE;
};

static vec<complex_lattice_t> complex_lattice_values;

/* For each complex variable, a pair of variables for the components exists in
   the hashtable.  */
static int_tree_htab_type *complex_variable_components;

/* For each complex SSA_NAME, a pair of ssa names for the components.  */
static vec<tree> complex_ssa_name_components;

/* Vector of PHI triplets (original complex PHI and corresponding real and
   imag PHIs if real and/or imag PHIs contain temporarily
   non-SSA_NAME/non-invariant args that need to be replaced by SSA_NAMEs.  */
static vec<gphi *> phis_to_revisit;

/* BBs that need EH cleanup.  */
static bitmap need_eh_cleanup;

/* Lookup UID in the complex_variable_components hashtable and return the
   associated tree.  */
static tree
cvc_lookup (unsigned int uid)
{
  struct int_tree_map in;
  in.uid = uid;
  return complex_variable_components->find_with_hash (in, uid).to;
}

/* Insert the pair UID, TO into the complex_variable_components hashtable.  */

static void
cvc_insert (unsigned int uid, tree to)
{
  int_tree_map h;
  int_tree_map *loc;

  h.uid = uid;
  loc = complex_variable_components->find_slot_with_hash (h, uid, INSERT);
  loc->uid = uid;
  loc->to = to;
}

/* Return true if T is not a zero constant.  In the case of real values,
   we're only interested in +0.0.  */

static int
some_nonzerop (tree t)
{
  int zerop = false;

  /* Operations with real or imaginary part of a complex number zero
     cannot be treated the same as operations with a real or imaginary
     operand if we care about the signs of zeros in the result.  */
  if (TREE_CODE (t) == REAL_CST && !flag_signed_zeros)
    zerop = real_identical (&TREE_REAL_CST (t), &dconst0);
  else if (TREE_CODE (t) == FIXED_CST)
    zerop = fixed_zerop (t);
  else if (TREE_CODE (t) == INTEGER_CST)
    zerop = integer_zerop (t);

  return !zerop;
}


/* Compute a lattice value from the components of a complex type REAL
   and IMAG.  */

static complex_lattice_t
find_lattice_value_parts (tree real, tree imag)
{
  int r, i;
  complex_lattice_t ret;

  r = some_nonzerop (real);
  i = some_nonzerop (imag);
  ret = r * ONLY_REAL + i * ONLY_IMAG;

  /* ??? On occasion we could do better than mapping 0+0i to real, but we
     certainly don't want to leave it UNINITIALIZED, which eventually gets
     mapped to VARYING.  */
  if (ret == UNINITIALIZED)
    ret = ONLY_REAL;

  return ret;
}


/* Compute a lattice value from gimple_val T.  */

static complex_lattice_t
find_lattice_value (tree t)
{
  tree real, imag;

  switch (TREE_CODE (t))
    {
    case SSA_NAME:
      return complex_lattice_values[SSA_NAME_VERSION (t)];

    case COMPLEX_CST:
      real = TREE_REALPART (t);
      imag = TREE_IMAGPART (t);
      break;

    default:
      gcc_unreachable ();
    }

  return find_lattice_value_parts (real, imag);
}

/* Determine if LHS is something for which we're interested in seeing
   simulation results.  */

static bool
is_complex_reg (tree lhs)
{
  return TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE && is_gimple_reg (lhs);
}

/* Mark the incoming parameters to the function as VARYING.  */

static void
init_parameter_lattice_values (void)
{
  tree parm, ssa_name;

  for (parm = DECL_ARGUMENTS (cfun->decl); parm ; parm = DECL_CHAIN (parm))
    if (is_complex_reg (parm)
	&& (ssa_name = ssa_default_def (cfun, parm)) != NULL_TREE)
      complex_lattice_values[SSA_NAME_VERSION (ssa_name)] = VARYING;
}

/* Initialize simulation state for each statement.  Return false if we
   found no statements we want to simulate, and thus there's nothing
   for the entire pass to do.  */

static bool
init_dont_simulate_again (void)
{
  basic_block bb;
  bool saw_a_complex_op = false;

  FOR_EACH_BB_FN (bb, cfun)
    {
      for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
	   gsi_next (&gsi))
	{
	  gphi *phi = gsi.phi ();
	  prop_set_simulate_again (phi,
				   is_complex_reg (gimple_phi_result (phi)));
	}

      for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
	   gsi_next (&gsi))
	{
	  gimple *stmt;
	  tree op0, op1;
	  bool sim_again_p;

	  stmt = gsi_stmt (gsi);
	  op0 = op1 = NULL_TREE;

	  /* Most control-altering statements must be initially
	     simulated, else we won't cover the entire cfg.  */
	  sim_again_p = stmt_ends_bb_p (stmt);

	  switch (gimple_code (stmt))
	    {
	    case GIMPLE_CALL:
	      if (gimple_call_lhs (stmt))
	        sim_again_p = is_complex_reg (gimple_call_lhs (stmt));
	      break;

	    case GIMPLE_ASSIGN:
	      sim_again_p = is_complex_reg (gimple_assign_lhs (stmt));
	      if (gimple_assign_rhs_code (stmt) == REALPART_EXPR
		  || gimple_assign_rhs_code (stmt) == IMAGPART_EXPR)
		op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
	      else
		op0 = gimple_assign_rhs1 (stmt);
	      if (gimple_num_ops (stmt) > 2)
		op1 = gimple_assign_rhs2 (stmt);
	      break;

	    case GIMPLE_COND:
	      op0 = gimple_cond_lhs (stmt);
	      op1 = gimple_cond_rhs (stmt);
	      break;

	    default:
	      break;
	    }

	  if (op0 || op1)
	    switch (gimple_expr_code (stmt))
	      {
	      case EQ_EXPR:
	      case NE_EXPR:
	      case PLUS_EXPR:
	      case MINUS_EXPR:
	      case MULT_EXPR:
	      case TRUNC_DIV_EXPR:
	      case CEIL_DIV_EXPR:
	      case FLOOR_DIV_EXPR:
	      case ROUND_DIV_EXPR:
	      case RDIV_EXPR:
		if (TREE_CODE (TREE_TYPE (op0)) == COMPLEX_TYPE
		    || TREE_CODE (TREE_TYPE (op1)) == COMPLEX_TYPE)
		  saw_a_complex_op = true;
		break;

	      case NEGATE_EXPR:
	      case CONJ_EXPR:
		if (TREE_CODE (TREE_TYPE (op0)) == COMPLEX_TYPE)
		  saw_a_complex_op = true;
		break;

	      case REALPART_EXPR:
	      case IMAGPART_EXPR:
		/* The total store transformation performed during
		  gimplification creates such uninitialized loads
		  and we need to lower the statement to be able
		  to fix things up.  */
		if (TREE_CODE (op0) == SSA_NAME
		    && ssa_undefined_value_p (op0))
		  saw_a_complex_op = true;
		break;

	      default:
		break;
	      }

	  prop_set_simulate_again (stmt, sim_again_p);
	}
    }

  return saw_a_complex_op;
}


/* Evaluate statement STMT against the complex lattice defined above.  */

enum ssa_prop_result
complex_propagate::visit_stmt (gimple *stmt, edge *taken_edge_p ATTRIBUTE_UNUSED,
			       tree *result_p)
{
  complex_lattice_t new_l, old_l, op1_l, op2_l;
  unsigned int ver;
  tree lhs;

  lhs = gimple_get_lhs (stmt);
  /* Skip anything but GIMPLE_ASSIGN and GIMPLE_CALL with a lhs.  */
  if (!lhs)
    return SSA_PROP_VARYING;

  /* These conditions should be satisfied due to the initial filter
     set up in init_dont_simulate_again.  */
  gcc_assert (TREE_CODE (lhs) == SSA_NAME);
  gcc_assert (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE);

  *result_p = lhs;
  ver = SSA_NAME_VERSION (lhs);
  old_l = complex_lattice_values[ver];

  switch (gimple_expr_code (stmt))
    {
    case SSA_NAME:
    case COMPLEX_CST:
      new_l = find_lattice_value (gimple_assign_rhs1 (stmt));
      break;

    case COMPLEX_EXPR:
      new_l = find_lattice_value_parts (gimple_assign_rhs1 (stmt),
				        gimple_assign_rhs2 (stmt));
      break;

    case PLUS_EXPR:
    case MINUS_EXPR:
      op1_l = find_lattice_value (gimple_assign_rhs1 (stmt));
      op2_l = find_lattice_value (gimple_assign_rhs2 (stmt));

      /* We've set up the lattice values such that IOR neatly
	 models addition.  */
      new_l = op1_l | op2_l;
      break;

    case MULT_EXPR:
    case RDIV_EXPR:
    case TRUNC_DIV_EXPR:
    case CEIL_DIV_EXPR:
    case FLOOR_DIV_EXPR:
    case ROUND_DIV_EXPR:
      op1_l = find_lattice_value (gimple_assign_rhs1 (stmt));
      op2_l = find_lattice_value (gimple_assign_rhs2 (stmt));

      /* Obviously, if either varies, so does the result.  */
      if (op1_l == VARYING || op2_l == VARYING)
	new_l = VARYING;
      /* Don't prematurely promote variables if we've not yet seen
	 their inputs.  */
      else if (op1_l == UNINITIALIZED)
	new_l = op2_l;
      else if (op2_l == UNINITIALIZED)
	new_l = op1_l;
      else
	{
	  /* At this point both numbers have only one component. If the
	     numbers are of opposite kind, the result is imaginary,
	     otherwise the result is real. The add/subtract translates
	     the real/imag from/to 0/1; the ^ performs the comparison.  */
	  new_l = ((op1_l - ONLY_REAL) ^ (op2_l - ONLY_REAL)) + ONLY_REAL;

	  /* Don't allow the lattice value to flip-flop indefinitely.  */
	  new_l |= old_l;
	}
      break;

    case NEGATE_EXPR:
    case CONJ_EXPR:
      new_l = find_lattice_value (gimple_assign_rhs1 (stmt));
      break;

    default:
      new_l = VARYING;
      break;
    }

  /* If nothing changed this round, let the propagator know.  */
  if (new_l == old_l)
    return SSA_PROP_NOT_INTERESTING;

  complex_lattice_values[ver] = new_l;
  return new_l == VARYING ? SSA_PROP_VARYING : SSA_PROP_INTERESTING;
}

/* Evaluate a PHI node against the complex lattice defined above.  */

enum ssa_prop_result
complex_propagate::visit_phi (gphi *phi)
{
  complex_lattice_t new_l, old_l;
  unsigned int ver;
  tree lhs;
  int i;

  lhs = gimple_phi_result (phi);

  /* This condition should be satisfied due to the initial filter
     set up in init_dont_simulate_again.  */
  gcc_assert (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE);

  /* We've set up the lattice values such that IOR neatly models PHI meet.  */
  new_l = UNINITIALIZED;
  for (i = gimple_phi_num_args (phi) - 1; i >= 0; --i)
    new_l |= find_lattice_value (gimple_phi_arg_def (phi, i));

  ver = SSA_NAME_VERSION (lhs);
  old_l = complex_lattice_values[ver];

  if (new_l == old_l)
    return SSA_PROP_NOT_INTERESTING;

  complex_lattice_values[ver] = new_l;
  return new_l == VARYING ? SSA_PROP_VARYING : SSA_PROP_INTERESTING;
}

/* Create one backing variable for a complex component of ORIG.  */

static tree
create_one_component_var (tree type, tree orig, const char *prefix,
			  const char *suffix, enum tree_code code)
{
  tree r = create_tmp_var (type, prefix);

  DECL_SOURCE_LOCATION (r) = DECL_SOURCE_LOCATION (orig);
  DECL_ARTIFICIAL (r) = 1;

  if (DECL_NAME (orig) && !DECL_IGNORED_P (orig))
    {
      const char *name = IDENTIFIER_POINTER (DECL_NAME (orig));
      name = ACONCAT ((name, suffix, NULL));
      DECL_NAME (r) = get_identifier (name);

      SET_DECL_DEBUG_EXPR (r, build1 (code, type, orig));
      DECL_HAS_DEBUG_EXPR_P (r) = 1;
      DECL_IGNORED_P (r) = 0;
      TREE_NO_WARNING (r) = TREE_NO_WARNING (orig);
    }
  else
    {
      DECL_IGNORED_P (r) = 1;
      TREE_NO_WARNING (r) = 1;
    }

  return r;
}

/* Retrieve a value for a complex component of VAR.  */

static tree
get_component_var (tree var, bool imag_p)
{
  size_t decl_index = DECL_UID (var) * 2 + imag_p;
  tree ret = cvc_lookup (decl_index);

  if (ret == NULL)
    {
      ret = create_one_component_var (TREE_TYPE (TREE_TYPE (var)), var,
				      imag_p ? "CI" : "CR",
				      imag_p ? "$imag" : "$real",
				      imag_p ? IMAGPART_EXPR : REALPART_EXPR);
      cvc_insert (decl_index, ret);
    }

  return ret;
}

/* Retrieve a value for a complex component of SSA_NAME.  */

static tree
get_component_ssa_name (tree ssa_name, bool imag_p)
{
  complex_lattice_t lattice = find_lattice_value (ssa_name);
  size_t ssa_name_index;
  tree ret;

  if (lattice == (imag_p ? ONLY_REAL : ONLY_IMAG))
    {
      tree inner_type = TREE_TYPE (TREE_TYPE (ssa_name));
      if (SCALAR_FLOAT_TYPE_P (inner_type))
	return build_real (inner_type, dconst0);
      else
	return build_int_cst (inner_type, 0);
    }

  ssa_name_index = SSA_NAME_VERSION (ssa_name) * 2 + imag_p;
  ret = complex_ssa_name_components[ssa_name_index];
  if (ret == NULL)
    {
      if (SSA_NAME_VAR (ssa_name))
	ret = get_component_var (SSA_NAME_VAR (ssa_name), imag_p);
      else
	ret = TREE_TYPE (TREE_TYPE (ssa_name));
      ret = make_ssa_name (ret);

      /* Copy some properties from the original.  In particular, whether it
	 is used in an abnormal phi, and whether it's uninitialized.  */
      SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ret)
	= SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssa_name);
      if (SSA_NAME_IS_DEFAULT_DEF (ssa_name)
	  && TREE_CODE (SSA_NAME_VAR (ssa_name)) == VAR_DECL)
	{
	  SSA_NAME_DEF_STMT (ret) = SSA_NAME_DEF_STMT (ssa_name);
	  set_ssa_default_def (cfun, SSA_NAME_VAR (ret), ret);
	}

      complex_ssa_name_components[ssa_name_index] = ret;
    }

  return ret;
}

/* Set a value for a complex component of SSA_NAME, return a
   gimple_seq of stuff that needs doing.  */

static gimple_seq
set_component_ssa_name (tree ssa_name, bool imag_p, tree value)
{
  complex_lattice_t lattice = find_lattice_value (ssa_name);
  size_t ssa_name_index;
  tree comp;
  gimple *last;
  gimple_seq list;

  /* We know the value must be zero, else there's a bug in our lattice
     analysis.  But the value may well be a variable known to contain
     zero.  We should be safe ignoring it.  */
  if (lattice == (imag_p ? ONLY_REAL : ONLY_IMAG))
    return NULL;

  /* If we've already assigned an SSA_NAME to this component, then this
     means that our walk of the basic blocks found a use before the set.
     This is fine.  Now we should create an initialization for the value
     we created earlier.  */
  ssa_name_index = SSA_NAME_VERSION (ssa_name) * 2 + imag_p;
  comp = complex_ssa_name_components[ssa_name_index];
  if (comp)
    ;

  /* If we've nothing assigned, and the value we're given is already stable,
     then install that as the value for this SSA_NAME.  This preemptively
     copy-propagates the value, which avoids unnecessary memory allocation.  */
  else if (is_gimple_min_invariant (value)
	   && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssa_name))
    {
      complex_ssa_name_components[ssa_name_index] = value;
      return NULL;
    }
  else if (TREE_CODE (value) == SSA_NAME
	   && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssa_name))
    {
      /* Replace an anonymous base value with the variable from cvc_lookup.
	 This should result in better debug info.  */
      if (!SSA_NAME_IS_DEFAULT_DEF (value)
	  && SSA_NAME_VAR (ssa_name)
	  && (!SSA_NAME_VAR (value) || DECL_IGNORED_P (SSA_NAME_VAR (value)))
	  && !DECL_IGNORED_P (SSA_NAME_VAR (ssa_name)))
	{
	  comp = get_component_var (SSA_NAME_VAR (ssa_name), imag_p);
	  replace_ssa_name_symbol (value, comp);
	}

      complex_ssa_name_components[ssa_name_index] = value;
      return NULL;
    }

  /* Finally, we need to stabilize the result by installing the value into
     a new ssa name.  */
  else
    comp = get_component_ssa_name (ssa_name, imag_p);

  /* Do all the work to assign VALUE to COMP.  */
  list = NULL;
  value = force_gimple_operand (value, &list, false, NULL);
  last =  gimple_build_assign (comp, value);
  gimple_seq_add_stmt (&list, last);
  gcc_assert (SSA_NAME_DEF_STMT (comp) == last);

  return list;
}

/* Extract the real or imaginary part of a complex variable or constant.
   Make sure that it's a proper gimple_val and gimplify it if not.
   Emit any new code before gsi.  */

static tree
extract_component (gimple_stmt_iterator *gsi, tree t, bool imagpart_p,
		   bool gimple_p, bool phiarg_p = false)
{
  switch (TREE_CODE (t))
    {
    case COMPLEX_CST:
      return imagpart_p ? TREE_IMAGPART (t) : TREE_REALPART (t);

    case COMPLEX_EXPR:
      gcc_unreachable ();

    case BIT_FIELD_REF:
      {
	tree inner_type = TREE_TYPE (TREE_TYPE (t));
	t = unshare_expr (t);
	TREE_TYPE (t) = inner_type;
	TREE_OPERAND (t, 1) = TYPE_SIZE (inner_type);
	if (imagpart_p)
	  TREE_OPERAND (t, 2) = size_binop (PLUS_EXPR, TREE_OPERAND (t, 2),
					    TYPE_SIZE (inner_type));
	if (gimple_p)
	  t = force_gimple_operand_gsi (gsi, t, true, NULL, true,
					GSI_SAME_STMT);
	return t;
      }

    case VAR_DECL:
    case RESULT_DECL:
    case PARM_DECL:
    case COMPONENT_REF:
    case ARRAY_REF:
    case VIEW_CONVERT_EXPR:
    case MEM_REF:
      {
	tree inner_type = TREE_TYPE (TREE_TYPE (t));

	t = build1 ((imagpart_p ? IMAGPART_EXPR : REALPART_EXPR),
		    inner_type, unshare_expr (t));

	if (gimple_p)
	  t = force_gimple_operand_gsi (gsi, t, true, NULL, true,
                                        GSI_SAME_STMT);

	return t;
      }

    case SSA_NAME:
      t = get_component_ssa_name (t, imagpart_p);
      if (TREE_CODE (t) == SSA_NAME && SSA_NAME_DEF_STMT (t) == NULL)
	gcc_assert (phiarg_p);
      return t;

    default:
      gcc_unreachable ();
    }
}

/* Update the complex components of the ssa name on the lhs of STMT.  */

static void
update_complex_components (gimple_stmt_iterator *gsi, gimple *stmt, tree r,
			   tree i)
{
  tree lhs;
  gimple_seq list;

  lhs = gimple_get_lhs (stmt);

  list = set_component_ssa_name (lhs, false, r);
  if (list)
    gsi_insert_seq_after (gsi, list, GSI_CONTINUE_LINKING);

  list = set_component_ssa_name (lhs, true, i);
  if (list)
    gsi_insert_seq_after (gsi, list, GSI_CONTINUE_LINKING);
}

static void
update_complex_components_on_edge (edge e, tree lhs, tree r, tree i)
{
  gimple_seq list;

  list = set_component_ssa_name (lhs, false, r);
  if (list)
    gsi_insert_seq_on_edge (e, list);

  list = set_component_ssa_name (lhs, true, i);
  if (list)
    gsi_insert_seq_on_edge (e, list);
}


/* Update an assignment to a complex variable in place.  */

static void
update_complex_assignment (gimple_stmt_iterator *gsi, tree r, tree i)
{
  gimple *old_stmt = gsi_stmt (*gsi);
  gimple_assign_set_rhs_with_ops (gsi, COMPLEX_EXPR, r, i);
  gimple *stmt = gsi_stmt (*gsi);
  update_stmt (stmt);
  if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
    bitmap_set_bit (need_eh_cleanup, gimple_bb (stmt)->index);

  update_complex_components (gsi, gsi_stmt (*gsi), r, i);
}


/* Generate code at the entry point of the function to initialize the
   component variables for a complex parameter.  */

static void
update_parameter_components (void)
{
  edge entry_edge = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun));
  tree parm;

  for (parm = DECL_ARGUMENTS (cfun->decl); parm ; parm = DECL_CHAIN (parm))
    {
      tree type = TREE_TYPE (parm);
      tree ssa_name, r, i;

      if (TREE_CODE (type) != COMPLEX_TYPE || !is_gimple_reg (parm))
	continue;

      type = TREE_TYPE (type);
      ssa_name = ssa_default_def (cfun, parm);
      if (!ssa_name)
	continue;

      r = build1 (REALPART_EXPR, type, ssa_name);
      i = build1 (IMAGPART_EXPR, type, ssa_name);
      update_complex_components_on_edge (entry_edge, ssa_name, r, i);
    }
}

/* Generate code to set the component variables of a complex variable
   to match the PHI statements in block BB.  */

static void
update_phi_components (basic_block bb)
{
  gphi_iterator gsi;

  for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    {
      gphi *phi = gsi.phi ();

      if (is_complex_reg (gimple_phi_result (phi)))
	{
	  gphi *p[2] = { NULL, NULL };
	  unsigned int i, j, n;
	  bool revisit_phi = false;

	  for (j = 0; j < 2; j++)
	    {
	      tree l = get_component_ssa_name (gimple_phi_result (phi), j > 0);
	      if (TREE_CODE (l) == SSA_NAME)
		p[j] = create_phi_node (l, bb);
	    }

	  for (i = 0, n = gimple_phi_num_args (phi); i < n; ++i)
	    {
	      tree comp, arg = gimple_phi_arg_def (phi, i);
	      for (j = 0; j < 2; j++)
		if (p[j])
		  {
		    comp = extract_component (NULL, arg, j > 0, false, true);
		    if (TREE_CODE (comp) == SSA_NAME
			&& SSA_NAME_DEF_STMT (comp) == NULL)
		      {
			/* For the benefit of any gimple simplification during
			   this pass that might walk SSA_NAME def stmts,
			   don't add SSA_NAMEs without definitions into the
			   PHI arguments, but put a decl in there instead
			   temporarily, and revisit this PHI later on.  */
			if (SSA_NAME_VAR (comp))
			  comp = SSA_NAME_VAR (comp);
			else
			  comp = create_tmp_reg (TREE_TYPE (comp),
						 get_name (comp));
			revisit_phi = true;
		      }
		    SET_PHI_ARG_DEF (p[j], i, comp);
		  }
	    }

	  if (revisit_phi)
	    {
	      phis_to_revisit.safe_push (phi);
	      phis_to_revisit.safe_push (p[0]);
	      phis_to_revisit.safe_push (p[1]);
	    }
	}
    }
}

/* Expand a complex move to scalars.  */

static void
expand_complex_move (gimple_stmt_iterator *gsi, tree type)
{
  tree inner_type = TREE_TYPE (type);
  tree r, i, lhs, rhs;
  gimple *stmt = gsi_stmt (*gsi);

  if (is_gimple_assign (stmt))
    {
      lhs = gimple_assign_lhs (stmt);
      if (gimple_num_ops (stmt) == 2)
	rhs = gimple_assign_rhs1 (stmt);
      else
	rhs = NULL_TREE;
    }
  else if (is_gimple_call (stmt))
    {
      lhs = gimple_call_lhs (stmt);
      rhs = NULL_TREE;
    }
  else
    gcc_unreachable ();

  if (TREE_CODE (lhs) == SSA_NAME)
    {
      if (is_ctrl_altering_stmt (stmt))
	{
	  edge e;

	  /* The value is not assigned on the exception edges, so we need not
	     concern ourselves there.  We do need to update on the fallthru
	     edge.  Find it.  */
	  e = find_fallthru_edge (gsi_bb (*gsi)->succs);
	  if (!e)
	    gcc_unreachable ();

	  r = build1 (REALPART_EXPR, inner_type, lhs);
	  i = build1 (IMAGPART_EXPR, inner_type, lhs);
	  update_complex_components_on_edge (e, lhs, r, i);
	}
      else if (is_gimple_call (stmt)
	       || gimple_has_side_effects (stmt)
	       || gimple_assign_rhs_code (stmt) == PAREN_EXPR)
	{
	  r = build1 (REALPART_EXPR, inner_type, lhs);
	  i = build1 (IMAGPART_EXPR, inner_type, lhs);
	  update_complex_components (gsi, stmt, r, i);
	}
      else
	{
	  if (gimple_assign_rhs_code (stmt) != COMPLEX_EXPR)
	    {
	      r = extract_component (gsi, rhs, 0, true);
	      i = extract_component (gsi, rhs, 1, true);
	    }
	  else
	    {
	      r = gimple_assign_rhs1 (stmt);
	      i = gimple_assign_rhs2 (stmt);
	    }
	  update_complex_assignment (gsi, r, i);
	}
    }
  else if (rhs && TREE_CODE (rhs) == SSA_NAME && !TREE_SIDE_EFFECTS (lhs))
    {
      tree x;
      gimple *t;
      location_t loc;

      loc = gimple_location (stmt);
      r = extract_component (gsi, rhs, 0, false);
      i = extract_component (gsi, rhs, 1, false);

      x = build1 (REALPART_EXPR, inner_type, unshare_expr (lhs));
      t = gimple_build_assign (x, r);
      gimple_set_location (t, loc);
      gsi_insert_before (gsi, t, GSI_SAME_STMT);

      if (stmt == gsi_stmt (*gsi))
	{
	  x = build1 (IMAGPART_EXPR, inner_type, unshare_expr (lhs));
	  gimple_assign_set_lhs (stmt, x);
	  gimple_assign_set_rhs1 (stmt, i);
	}
      else
	{
	  x = build1 (IMAGPART_EXPR, inner_type, unshare_expr (lhs));
	  t = gimple_build_assign (x, i);
	  gimple_set_location (t, loc);
	  gsi_insert_before (gsi, t, GSI_SAME_STMT);

	  stmt = gsi_stmt (*gsi);
	  gcc_assert (gimple_code (stmt) == GIMPLE_RETURN);
	  gimple_return_set_retval (as_a <greturn *> (stmt), lhs);
	}

      update_stmt (stmt);
    }
}

/* Expand complex addition to scalars:
	a + b = (ar + br) + i(ai + bi)
	a - b = (ar - br) + i(ai + bi)
*/

static void
expand_complex_addition (gimple_stmt_iterator *gsi, tree inner_type,
			 tree ar, tree ai, tree br, tree bi,
			 enum tree_code code,
			 complex_lattice_t al, complex_lattice_t bl)
{
  tree rr, ri;

  switch (PAIR (al, bl))
    {
    case PAIR (ONLY_REAL, ONLY_REAL):
      rr = gimplify_build2 (gsi, code, inner_type, ar, br);
      ri = ai;
      break;

    case PAIR (ONLY_REAL, ONLY_IMAG):
      rr = ar;
      if (code == MINUS_EXPR)
	ri = gimplify_build2 (gsi, MINUS_EXPR, inner_type, ai, bi);
      else
	ri = bi;
      break;

    case PAIR (ONLY_IMAG, ONLY_REAL):
      if (code == MINUS_EXPR)
	rr = gimplify_build2 (gsi, MINUS_EXPR, inner_type, ar, br);
      else
	rr = br;
      ri = ai;
      break;

    case PAIR (ONLY_IMAG, ONLY_IMAG):
      rr = ar;
      ri = gimplify_build2 (gsi, code, inner_type, ai, bi);
      break;

    case PAIR (VARYING, ONLY_REAL):
      rr = gimplify_build2 (gsi, code, inner_type, ar, br);
      ri = ai;
      break;

    case PAIR (VARYING, ONLY_IMAG):
      rr = ar;
      ri = gimplify_build2 (gsi, code, inner_type, ai, bi);
      break;

    case PAIR (ONLY_REAL, VARYING):
      if (code == MINUS_EXPR)
	goto general;
      rr = gimplify_build2 (gsi, code, inner_type, ar, br);
      ri = bi;
      break;

    case PAIR (ONLY_IMAG, VARYING):
      if (code == MINUS_EXPR)
	goto general;
      rr = br;
      ri = gimplify_build2 (gsi, code, inner_type, ai, bi);
      break;

    case PAIR (VARYING, VARYING):
    general:
      rr = gimplify_build2 (gsi, code, inner_type, ar, br);
      ri = gimplify_build2 (gsi, code, inner_type, ai, bi);
      break;

    default:
      gcc_unreachable ();
    }

  update_complex_assignment (gsi, rr, ri);
}

/* Expand a complex multiplication or division to a libcall to the c99
   compliant routines.  TYPE is the complex type of the operation.
   If INPLACE_P replace the statement at GSI with
   the libcall and return NULL_TREE.  Else insert the call, assign its
   result to an output variable and return that variable.  If INPLACE_P
   is true then the statement being replaced should be an assignment
   statement.  */

static tree
expand_complex_libcall (gimple_stmt_iterator *gsi, tree type, tree ar, tree ai,
			tree br, tree bi, enum tree_code code, bool inplace_p)
{
  machine_mode mode;
  enum built_in_function bcode;
  tree fn, lhs;
  gcall *stmt;

  mode = TYPE_MODE (type);
  gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);

  if (code == MULT_EXPR)
    bcode = ((enum built_in_function)
	     (BUILT_IN_COMPLEX_MUL_MIN + mode - MIN_MODE_COMPLEX_FLOAT));
  else if (code == RDIV_EXPR)
    bcode = ((enum built_in_function)
	     (BUILT_IN_COMPLEX_DIV_MIN + mode - MIN_MODE_COMPLEX_FLOAT));
  else
    gcc_unreachable ();
  fn = builtin_decl_explicit (bcode);
  stmt = gimple_build_call (fn, 4, ar, ai, br, bi);

  if (inplace_p)
    {
      gimple *old_stmt = gsi_stmt (*gsi);
      gimple_call_set_nothrow (stmt, !stmt_could_throw_p (cfun, old_stmt));
      lhs = gimple_assign_lhs (old_stmt);
      gimple_call_set_lhs (stmt, lhs);
      gsi_replace (gsi, stmt, true);

      type = TREE_TYPE (type);
      if (stmt_can_throw_internal (cfun, stmt))
	{
	  edge_iterator ei;
	  edge e;
	  FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs)
	      if (!(e->flags & EDGE_EH))
		break;
	  basic_block bb = split_edge (e);
	  gimple_stmt_iterator gsi2 = gsi_start_bb (bb);
	  update_complex_components (&gsi2, stmt,
				     build1 (REALPART_EXPR, type, lhs),
				     build1 (IMAGPART_EXPR, type, lhs));
	  return NULL_TREE;
	}
      else
	update_complex_components (gsi, stmt,
				   build1 (REALPART_EXPR, type, lhs),
				   build1 (IMAGPART_EXPR, type, lhs));
      SSA_NAME_DEF_STMT (lhs) = stmt;
      return NULL_TREE;
    }

  gimple_call_set_nothrow (stmt, true);
  lhs = make_ssa_name (type);
  gimple_call_set_lhs (stmt, lhs);
  gsi_insert_before (gsi, stmt, GSI_SAME_STMT);

  return lhs;
}

/* Perform a complex multiplication on two complex constants A, B represented
   by AR, AI, BR, BI of type TYPE.
   The operation we want is: a * b = (ar*br - ai*bi) + i(ar*bi + br*ai).
   Insert the GIMPLE statements into GSI.  Store the real and imaginary
   components of the result into RR and RI.  */

static void
expand_complex_multiplication_components (gimple_stmt_iterator *gsi,
					     tree type, tree ar, tree ai,
					     tree br, tree bi,
					     tree *rr, tree *ri)
{
  tree t1, t2, t3, t4;

  t1 = gimplify_build2 (gsi, MULT_EXPR, type, ar, br);
  t2 = gimplify_build2 (gsi, MULT_EXPR, type, ai, bi);
  t3 = gimplify_build2 (gsi, MULT_EXPR, type, ar, bi);

  /* Avoid expanding redundant multiplication for the common
     case of squaring a complex number.  */
  if (ar == br && ai == bi)
    t4 = t3;
  else
    t4 = gimplify_build2 (gsi, MULT_EXPR, type, ai, br);

  *rr = gimplify_build2 (gsi, MINUS_EXPR, type, t1, t2);
  *ri = gimplify_build2 (gsi, PLUS_EXPR, type, t3, t4);
}

/* Expand complex multiplication to scalars:
	a * b = (ar*br - ai*bi) + i(ar*bi + br*ai)
*/

static void
expand_complex_multiplication (gimple_stmt_iterator *gsi, tree type,
			       tree ar, tree ai, tree br, tree bi,
			       complex_lattice_t al, complex_lattice_t bl)
{
  tree rr, ri;
  tree inner_type = TREE_TYPE (type);

  if (al < bl)
    {
      complex_lattice_t tl;
      rr = ar, ar = br, br = rr;
      ri = ai, ai = bi, bi = ri;
      tl = al, al = bl, bl = tl;
    }

  switch (PAIR (al, bl))
    {
    case PAIR (ONLY_REAL, ONLY_REAL):
      rr = gimplify_build2 (gsi, MULT_EXPR, inner_type, ar, br);
      ri = ai;
      break;

    case PAIR (ONLY_IMAG, ONLY_REAL):
      rr = ar;
      if (TREE_CODE (ai) == REAL_CST
	  && real_identical (&TREE_REAL_CST (ai), &dconst1))
	ri = br;
      else
	ri = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, br);
      break;

    case PAIR (ONLY_IMAG, ONLY_IMAG):
      rr = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, bi);
      rr = gimplify_build1 (gsi, NEGATE_EXPR, inner_type, rr);
      ri = ar;
      break;

    case PAIR (VARYING, ONLY_REAL):
      rr = gimplify_build2 (gsi, MULT_EXPR, inner_type, ar, br);
      ri = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, br);
      break;

    case PAIR (VARYING, ONLY_IMAG):
      rr = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, bi);
      rr = gimplify_build1 (gsi, NEGATE_EXPR, inner_type, rr);
      ri = gimplify_build2 (gsi, MULT_EXPR, inner_type, ar, bi);
      break;

    case PAIR (VARYING, VARYING):
      if (flag_complex_method == 2 && SCALAR_FLOAT_TYPE_P (inner_type))
	{
	  /* If optimizing for size or not at all just do a libcall.
	     Same if there are exception-handling edges or signaling NaNs.  */
	  if (optimize == 0 || optimize_bb_for_size_p (gsi_bb (*gsi))
	     || stmt_can_throw_internal (cfun, gsi_stmt (*gsi))
	     || flag_signaling_nans)
	    {
	      expand_complex_libcall (gsi, type, ar, ai, br, bi,
				      MULT_EXPR, true);
	      return;
	    }

	  /* Else, expand x = a * b into
	     x = (ar*br - ai*bi) + i(ar*bi + br*ai);
	     if (isunordered (__real__ x, __imag__ x))
		x = __muldc3 (a, b);  */

	  tree tmpr, tmpi;
	  expand_complex_multiplication_components (gsi, inner_type, ar, ai,
						     br, bi, &tmpr, &tmpi);

	  gimple *check
	    = gimple_build_cond (UNORDERED_EXPR, tmpr, tmpi,
				 NULL_TREE, NULL_TREE);

	  basic_block orig_bb = gsi_bb (*gsi);
	  /* We want to keep track of the original complex multiplication
	     statement as we're going to modify it later in
	     update_complex_assignment.  Make sure that insert_cond_bb leaves
	     that statement in the join block.  */
	  gsi_prev (gsi);
	  basic_block cond_bb
	    = insert_cond_bb (gsi_bb (*gsi), gsi_stmt (*gsi), check,
			      profile_probability::very_unlikely ());


	  gimple_stmt_iterator cond_bb_gsi = gsi_last_bb (cond_bb);
	  gsi_insert_after (&cond_bb_gsi, gimple_build_nop (), GSI_NEW_STMT);

	  tree libcall_res
	    = expand_complex_libcall (&cond_bb_gsi, type, ar, ai, br,
				       bi, MULT_EXPR, false);
	  tree cond_real = gimplify_build1 (&cond_bb_gsi, REALPART_EXPR,
					    inner_type, libcall_res);
	  tree cond_imag = gimplify_build1 (&cond_bb_gsi, IMAGPART_EXPR,
					    inner_type, libcall_res);

	  basic_block join_bb = single_succ_edge (cond_bb)->dest;
	  *gsi = gsi_start_nondebug_after_labels_bb (join_bb);

	  /* We have a conditional block with some assignments in cond_bb.
	     Wire up the PHIs to wrap up.  */
	  rr = make_ssa_name (inner_type);
	  ri = make_ssa_name (inner_type);
	  edge cond_to_join = single_succ_edge (cond_bb);
	  edge orig_to_join = find_edge (orig_bb, join_bb);

	  gphi *real_phi = create_phi_node (rr, gsi_bb (*gsi));
	  add_phi_arg (real_phi, cond_real, cond_to_join,
			UNKNOWN_LOCATION);
	  add_phi_arg (real_phi, tmpr, orig_to_join, UNKNOWN_LOCATION);

	  gphi *imag_phi = create_phi_node (ri, gsi_bb (*gsi));
	  add_phi_arg (imag_phi, cond_imag, cond_to_join,
			UNKNOWN_LOCATION);
	  add_phi_arg (imag_phi, tmpi, orig_to_join, UNKNOWN_LOCATION);
	}
      else
	/* If we are not worrying about NaNs expand to
	  (ar*br - ai*bi) + i(ar*bi + br*ai) directly.  */
	expand_complex_multiplication_components (gsi, inner_type, ar, ai,
						      br, bi, &rr, &ri);
      break;

    default:
      gcc_unreachable ();
    }

  update_complex_assignment (gsi, rr, ri);
}

/* Keep this algorithm in sync with fold-const.c:const_binop().

   Expand complex division to scalars, straightforward algorithm.
	a / b = ((ar*br + ai*bi)/t) + i((ai*br - ar*bi)/t)
	    t = br*br + bi*bi
*/

static void
expand_complex_div_straight (gimple_stmt_iterator *gsi, tree inner_type,
			     tree ar, tree ai, tree br, tree bi,
			     enum tree_code code)
{
  tree rr, ri, div, t1, t2, t3;

  t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, br, br);
  t2 = gimplify_build2 (gsi, MULT_EXPR, inner_type, bi, bi);
  div = gimplify_build2 (gsi, PLUS_EXPR, inner_type, t1, t2);

  t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ar, br);
  t2 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, bi);
  t3 = gimplify_build2 (gsi, PLUS_EXPR, inner_type, t1, t2);
  rr = gimplify_build2 (gsi, code, inner_type, t3, div);

  t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, br);
  t2 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ar, bi);
  t3 = gimplify_build2 (gsi, MINUS_EXPR, inner_type, t1, t2);
  ri = gimplify_build2 (gsi, code, inner_type, t3, div);

  update_complex_assignment (gsi, rr, ri);
}

/* Keep this algorithm in sync with fold-const.c:const_binop().

   Expand complex division to scalars, modified algorithm to minimize
   overflow with wide input ranges.  */

static void
expand_complex_div_wide (gimple_stmt_iterator *gsi, tree inner_type,
			 tree ar, tree ai, tree br, tree bi,
			 enum tree_code code)
{
  tree rr, ri, ratio, div, t1, t2, tr, ti, compare;
  basic_block bb_cond, bb_true, bb_false, bb_join;
  gimple *stmt;

  /* Examine |br| < |bi|, and branch.  */
  t1 = gimplify_build1 (gsi, ABS_EXPR, inner_type, br);
  t2 = gimplify_build1 (gsi, ABS_EXPR, inner_type, bi);
  compare = fold_build2_loc (gimple_location (gsi_stmt (*gsi)),
			     LT_EXPR, boolean_type_node, t1, t2);
  STRIP_NOPS (compare);

  bb_cond = bb_true = bb_false = bb_join = NULL;
  rr = ri = tr = ti = NULL;
  if (TREE_CODE (compare) != INTEGER_CST)
    {
      edge e;
      gimple *stmt;
      tree cond, tmp;

      tmp = make_ssa_name (boolean_type_node);
      stmt = gimple_build_assign (tmp, compare);
      gsi_insert_before (gsi, stmt, GSI_SAME_STMT);

      cond = fold_build2_loc (gimple_location (stmt),
			  EQ_EXPR, boolean_type_node, tmp, boolean_true_node);
      stmt = gimple_build_cond_from_tree (cond, NULL_TREE, NULL_TREE);
      gsi_insert_before (gsi, stmt, GSI_SAME_STMT);

      /* Split the original block, and create the TRUE and FALSE blocks.  */
      e = split_block (gsi_bb (*gsi), stmt);
      bb_cond = e->src;
      bb_join = e->dest;
      bb_true = create_empty_bb (bb_cond);
      bb_false = create_empty_bb (bb_true);
      bb_true->count = bb_false->count
	 = bb_cond->count.apply_probability (profile_probability::even ());

      /* Wire the blocks together.  */
      e->flags = EDGE_TRUE_VALUE;
      /* TODO: With value profile we could add an historgram to determine real
	 branch outcome.  */
      e->probability = profile_probability::even ();
      redirect_edge_succ (e, bb_true);
      edge e2 = make_edge (bb_cond, bb_false, EDGE_FALSE_VALUE);
      e2->probability = profile_probability::even ();
      make_single_succ_edge (bb_true, bb_join, EDGE_FALLTHRU);
      make_single_succ_edge (bb_false, bb_join, EDGE_FALLTHRU);
      add_bb_to_loop (bb_true, bb_cond->loop_father);
      add_bb_to_loop (bb_false, bb_cond->loop_father);

      /* Update dominance info.  Note that bb_join's data was
         updated by split_block.  */
      if (dom_info_available_p (CDI_DOMINATORS))
        {
          set_immediate_dominator (CDI_DOMINATORS, bb_true, bb_cond);
          set_immediate_dominator (CDI_DOMINATORS, bb_false, bb_cond);
        }

      rr = create_tmp_reg (inner_type);
      ri = create_tmp_reg (inner_type);
    }

  /* In the TRUE branch, we compute
      ratio = br/bi;
      div = (br * ratio) + bi;
      tr = (ar * ratio) + ai;
      ti = (ai * ratio) - ar;
      tr = tr / div;
      ti = ti / div;  */
  if (bb_true || integer_nonzerop (compare))
    {
      if (bb_true)
	{
	  *gsi = gsi_last_bb (bb_true);
	  gsi_insert_after (gsi, gimple_build_nop (), GSI_NEW_STMT);
	}

      ratio = gimplify_build2 (gsi, code, inner_type, br, bi);

      t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, br, ratio);
      div = gimplify_build2 (gsi, PLUS_EXPR, inner_type, t1, bi);

      t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ar, ratio);
      tr = gimplify_build2 (gsi, PLUS_EXPR, inner_type, t1, ai);

      t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, ratio);
      ti = gimplify_build2 (gsi, MINUS_EXPR, inner_type, t1, ar);

      tr = gimplify_build2 (gsi, code, inner_type, tr, div);
      ti = gimplify_build2 (gsi, code, inner_type, ti, div);

     if (bb_true)
       {
	 stmt = gimple_build_assign (rr, tr);
	 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
	 stmt = gimple_build_assign (ri, ti);
	 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
	 gsi_remove (gsi, true);
       }
    }

  /* In the FALSE branch, we compute
      ratio = d/c;
      divisor = (d * ratio) + c;
      tr = (b * ratio) + a;
      ti = b - (a * ratio);
      tr = tr / div;
      ti = ti / div;  */
  if (bb_false || integer_zerop (compare))
    {
      if (bb_false)
	{
	  *gsi = gsi_last_bb (bb_false);
	  gsi_insert_after (gsi, gimple_build_nop (), GSI_NEW_STMT);
	}

      ratio = gimplify_build2 (gsi, code, inner_type, bi, br);

      t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, bi, ratio);
      div = gimplify_build2 (gsi, PLUS_EXPR, inner_type, t1, br);

      t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, ratio);
      tr = gimplify_build2 (gsi, PLUS_EXPR, inner_type, t1, ar);

      t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ar, ratio);
      ti = gimplify_build2 (gsi, MINUS_EXPR, inner_type, ai, t1);

      tr = gimplify_build2 (gsi, code, inner_type, tr, div);
      ti = gimplify_build2 (gsi, code, inner_type, ti, div);

     if (bb_false)
       {
	 stmt = gimple_build_assign (rr, tr);
	 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
	 stmt = gimple_build_assign (ri, ti);
	 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
	 gsi_remove (gsi, true);
       }
    }

  if (bb_join)
    *gsi = gsi_start_bb (bb_join);
  else
    rr = tr, ri = ti;

  update_complex_assignment (gsi, rr, ri);
}

/* Expand complex division to scalars.  */

static void
expand_complex_division (gimple_stmt_iterator *gsi, tree type,
			 tree ar, tree ai, tree br, tree bi,
			 enum tree_code code,
			 complex_lattice_t al, complex_lattice_t bl)
{
  tree rr, ri;

  tree inner_type = TREE_TYPE (type);
  switch (PAIR (al, bl))
    {
    case PAIR (ONLY_REAL, ONLY_REAL):
      rr = gimplify_build2 (gsi, code, inner_type, ar, br);
      ri = ai;
      break;

    case PAIR (ONLY_REAL, ONLY_IMAG):
      rr = ai;
      ri = gimplify_build2 (gsi, code, inner_type, ar, bi);
      ri = gimplify_build1 (gsi, NEGATE_EXPR, inner_type, ri);
      break;

    case PAIR (ONLY_IMAG, ONLY_REAL):
      rr = ar;
      ri = gimplify_build2 (gsi, code, inner_type, ai, br);
      break;

    case PAIR (ONLY_IMAG, ONLY_IMAG):
      rr = gimplify_build2 (gsi, code, inner_type, ai, bi);
      ri = ar;
      break;

    case PAIR (VARYING, ONLY_REAL):
      rr = gimplify_build2 (gsi, code, inner_type, ar, br);
      ri = gimplify_build2 (gsi, code, inner_type, ai, br);
      break;

    case PAIR (VARYING, ONLY_IMAG):
      rr = gimplify_build2 (gsi, code, inner_type, ai, bi);
      ri = gimplify_build2 (gsi, code, inner_type, ar, bi);
      ri = gimplify_build1 (gsi, NEGATE_EXPR, inner_type, ri);
      break;

    case PAIR (ONLY_REAL, VARYING):
    case PAIR (ONLY_IMAG, VARYING):
    case PAIR (VARYING, VARYING):
      switch (flag_complex_method)
	{
	case 0:
	  /* straightforward implementation of complex divide acceptable.  */
	  expand_complex_div_straight (gsi, inner_type, ar, ai, br, bi, code);
	  break;

	case 2:
	  if (SCALAR_FLOAT_TYPE_P (inner_type))
	    {
	      expand_complex_libcall (gsi, type, ar, ai, br, bi, code, true);
	      break;
	    }
	  /* FALLTHRU */

	case 1:
	  /* wide ranges of inputs must work for complex divide.  */
	  expand_complex_div_wide (gsi, inner_type, ar, ai, br, bi, code);
	  break;

	default:
	  gcc_unreachable ();
	}
      return;

    default:
      gcc_unreachable ();
    }

  update_complex_assignment (gsi, rr, ri);
}

/* Expand complex negation to scalars:
	-a = (-ar) + i(-ai)
*/

static void
expand_complex_negation (gimple_stmt_iterator *gsi, tree inner_type,
			 tree ar, tree ai)
{
  tree rr, ri;

  rr = gimplify_build1 (gsi, NEGATE_EXPR, inner_type, ar);
  ri = gimplify_build1 (gsi, NEGATE_EXPR, inner_type, ai);

  update_complex_assignment (gsi, rr, ri);
}

/* Expand complex conjugate to scalars:
	~a = (ar) + i(-ai)
*/

static void
expand_complex_conjugate (gimple_stmt_iterator *gsi, tree inner_type,
			  tree ar, tree ai)
{
  tree ri;

  ri = gimplify_build1 (gsi, NEGATE_EXPR, inner_type, ai);

  update_complex_assignment (gsi, ar, ri);
}

/* Expand complex comparison (EQ or NE only).  */

static void
expand_complex_comparison (gimple_stmt_iterator *gsi, tree ar, tree ai,
			   tree br, tree bi, enum tree_code code)
{
  tree cr, ci, cc, type;
  gimple *stmt;

  cr = gimplify_build2 (gsi, code, boolean_type_node, ar, br);
  ci = gimplify_build2 (gsi, code, boolean_type_node, ai, bi);
  cc = gimplify_build2 (gsi,
			(code == EQ_EXPR ? TRUTH_AND_EXPR : TRUTH_OR_EXPR),
			boolean_type_node, cr, ci);

  stmt = gsi_stmt (*gsi);

  switch (gimple_code (stmt))
    {
    case GIMPLE_RETURN:
      {
	greturn *return_stmt = as_a <greturn *> (stmt);
	type = TREE_TYPE (gimple_return_retval (return_stmt));
	gimple_return_set_retval (return_stmt, fold_convert (type, cc));
      }
      break;

    case GIMPLE_ASSIGN:
      type = TREE_TYPE (gimple_assign_lhs (stmt));
      gimple_assign_set_rhs_from_tree (gsi, fold_convert (type, cc));
      stmt = gsi_stmt (*gsi);
      break;

    case GIMPLE_COND:
      {
	gcond *cond_stmt = as_a <gcond *> (stmt);
	gimple_cond_set_code (cond_stmt, EQ_EXPR);
	gimple_cond_set_lhs (cond_stmt, cc);
	gimple_cond_set_rhs (cond_stmt, boolean_true_node);
      }
      break;

    default:
      gcc_unreachable ();
    }

  update_stmt (stmt);
  if (maybe_clean_eh_stmt (stmt))
    bitmap_set_bit (need_eh_cleanup, gimple_bb (stmt)->index);
}

/* Expand inline asm that sets some complex SSA_NAMEs.  */

static void
expand_complex_asm (gimple_stmt_iterator *gsi)
{
  gasm *stmt = as_a <gasm *> (gsi_stmt (*gsi));
  unsigned int i;

  for (i = 0; i < gimple_asm_noutputs (stmt); ++i)
    {
      tree link = gimple_asm_output_op (stmt, i);
      tree op = TREE_VALUE (link);
      if (TREE_CODE (op) == SSA_NAME
	  && TREE_CODE (TREE_TYPE (op)) == COMPLEX_TYPE)
	{
	  tree type = TREE_TYPE (op);
	  tree inner_type = TREE_TYPE (type);
	  tree r = build1 (REALPART_EXPR, inner_type, op);
	  tree i = build1 (IMAGPART_EXPR, inner_type, op);
	  gimple_seq list = set_component_ssa_name (op, false, r);

	  if (list)
	    gsi_insert_seq_after (gsi, list, GSI_CONTINUE_LINKING);

	  list = set_component_ssa_name (op, true, i);
	  if (list)
	    gsi_insert_seq_after (gsi, list, GSI_CONTINUE_LINKING);
	}
    }
}

/* Process one statement.  If we identify a complex operation, expand it.  */

static void
expand_complex_operations_1 (gimple_stmt_iterator *gsi)
{
  gimple *stmt = gsi_stmt (*gsi);
  tree type, inner_type, lhs;
  tree ac, ar, ai, bc, br, bi;
  complex_lattice_t al, bl;
  enum tree_code code;

  if (gimple_code (stmt) == GIMPLE_ASM)
    {
      expand_complex_asm (gsi);
      return;
    }

  lhs = gimple_get_lhs (stmt);
  if (!lhs && gimple_code (stmt) != GIMPLE_COND)
    return;

  type = TREE_TYPE (gimple_op (stmt, 0));
  code = gimple_expr_code (stmt);

  /* Initial filter for operations we handle.  */
  switch (code)
    {
    case PLUS_EXPR:
    case MINUS_EXPR:
    case MULT_EXPR:
    case TRUNC_DIV_EXPR:
    case CEIL_DIV_EXPR:
    case FLOOR_DIV_EXPR:
    case ROUND_DIV_EXPR:
    case RDIV_EXPR:
    case NEGATE_EXPR:
    case CONJ_EXPR:
      if (TREE_CODE (type) != COMPLEX_TYPE)
	return;
      inner_type = TREE_TYPE (type);
      break;

    case EQ_EXPR:
    case NE_EXPR:
      /* Note, both GIMPLE_ASSIGN and GIMPLE_COND may have an EQ_EXPR
	 subcode, so we need to access the operands using gimple_op.  */
      inner_type = TREE_TYPE (gimple_op (stmt, 1));
      if (TREE_CODE (inner_type) != COMPLEX_TYPE)
	return;
      break;

    default:
      {
	tree rhs;

	/* GIMPLE_COND may also fallthru here, but we do not need to
	   do anything with it.  */
	if (gimple_code (stmt) == GIMPLE_COND)
	  return;

	if (TREE_CODE (type) == COMPLEX_TYPE)
	  expand_complex_move (gsi, type);
	else if (is_gimple_assign (stmt)
		 && (gimple_assign_rhs_code (stmt) == REALPART_EXPR
		     || gimple_assign_rhs_code (stmt) == IMAGPART_EXPR)
		 && TREE_CODE (lhs) == SSA_NAME)
	  {
	    rhs = gimple_assign_rhs1 (stmt);
	    rhs = extract_component (gsi, TREE_OPERAND (rhs, 0),
		                     gimple_assign_rhs_code (stmt)
				       == IMAGPART_EXPR,
				     false);
	    gimple_assign_set_rhs_from_tree (gsi, rhs);
	    stmt = gsi_stmt (*gsi);
	    update_stmt (stmt);
	  }
      }
      return;
    }

  /* Extract the components of the two complex values.  Make sure and
     handle the common case of the same value used twice specially.  */
  if (is_gimple_assign (stmt))
    {
      ac = gimple_assign_rhs1 (stmt);
      bc = (gimple_num_ops (stmt) > 2) ? gimple_assign_rhs2 (stmt) : NULL;
    }
  /* GIMPLE_CALL cannot get here.  */
  else
    {
      ac = gimple_cond_lhs (stmt);
      bc = gimple_cond_rhs (stmt);
    }

  ar = extract_component (gsi, ac, false, true);
  ai = extract_component (gsi, ac, true, true);

  if (ac == bc)
    br = ar, bi = ai;
  else if (bc)
    {
      br = extract_component (gsi, bc, 0, true);
      bi = extract_component (gsi, bc, 1, true);
    }
  else
    br = bi = NULL_TREE;

  al = find_lattice_value (ac);
  if (al == UNINITIALIZED)
    al = VARYING;

  if (TREE_CODE_CLASS (code) == tcc_unary)
    bl = UNINITIALIZED;
  else if (ac == bc)
    bl = al;
  else
    {
      bl = find_lattice_value (bc);
      if (bl == UNINITIALIZED)
	bl = VARYING;
    }

  switch (code)
    {
    case PLUS_EXPR:
    case MINUS_EXPR:
      expand_complex_addition (gsi, inner_type, ar, ai, br, bi, code, al, bl);
      break;

    case MULT_EXPR:
      expand_complex_multiplication (gsi, type, ar, ai, br, bi, al, bl);
      break;

    case TRUNC_DIV_EXPR:
    case CEIL_DIV_EXPR:
    case FLOOR_DIV_EXPR:
    case ROUND_DIV_EXPR:
    case RDIV_EXPR:
      expand_complex_division (gsi, type, ar, ai, br, bi, code, al, bl);
      break;

    case NEGATE_EXPR:
      expand_complex_negation (gsi, inner_type, ar, ai);
      break;

    case CONJ_EXPR:
      expand_complex_conjugate (gsi, inner_type, ar, ai);
      break;

    case EQ_EXPR:
    case NE_EXPR:
      expand_complex_comparison (gsi, ar, ai, br, bi, code);
      break;

    default:
      gcc_unreachable ();
    }
}


/* Entry point for complex operation lowering during optimization.  */

static unsigned int
tree_lower_complex (void)
{
  gimple_stmt_iterator gsi;
  basic_block bb;
  int n_bbs, i;
  int *rpo;

  if (!init_dont_simulate_again ())
    return 0;

  complex_lattice_values.create (num_ssa_names);
  complex_lattice_values.safe_grow_cleared (num_ssa_names);

  init_parameter_lattice_values ();
  class complex_propagate complex_propagate;
  complex_propagate.ssa_propagate ();

  need_eh_cleanup = BITMAP_ALLOC (NULL);

  complex_variable_components = new int_tree_htab_type (10);

  complex_ssa_name_components.create (2 * num_ssa_names);
  complex_ssa_name_components.safe_grow_cleared (2 * num_ssa_names);

  update_parameter_components ();

  rpo = XNEWVEC (int, last_basic_block_for_fn (cfun));
  n_bbs = pre_and_rev_post_order_compute (NULL, rpo, false);
  for (i = 0; i < n_bbs; i++)
    {
      bb = BASIC_BLOCK_FOR_FN (cfun, rpo[i]);
      if (!bb)
	continue;
      update_phi_components (bb);
      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
	expand_complex_operations_1 (&gsi);
    }

  free (rpo);

  if (!phis_to_revisit.is_empty ())
    {
      unsigned int n = phis_to_revisit.length ();
      for (unsigned int j = 0; j < n; j += 3)
	for (unsigned int k = 0; k < 2; k++)
	  if (gphi *phi = phis_to_revisit[j + k + 1])
	    {
	      unsigned int m = gimple_phi_num_args (phi);
	      for (unsigned int l = 0; l < m; ++l)
		{
		  tree op = gimple_phi_arg_def (phi, l);
		  if (TREE_CODE (op) == SSA_NAME
		      || is_gimple_min_invariant (op))
		    continue;
		  tree arg = gimple_phi_arg_def (phis_to_revisit[j], l);
		  op = extract_component (NULL, arg, k > 0, false, false);
		  SET_PHI_ARG_DEF (phi, l, op);
		}
	    }
      phis_to_revisit.release ();
    }

  gsi_commit_edge_inserts ();

  unsigned todo
    = gimple_purge_all_dead_eh_edges (need_eh_cleanup) ? TODO_cleanup_cfg : 0;
  BITMAP_FREE (need_eh_cleanup);

  delete complex_variable_components;
  complex_variable_components = NULL;
  complex_ssa_name_components.release ();
  complex_lattice_values.release ();
  return todo;
}

namespace {

const pass_data pass_data_lower_complex =
{
  GIMPLE_PASS, /* type */
  "cplxlower", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_NONE, /* tv_id */
  PROP_ssa, /* properties_required */
  PROP_gimple_lcx, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  TODO_update_ssa, /* todo_flags_finish */
};

class pass_lower_complex : public gimple_opt_pass
{
public:
  pass_lower_complex (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_lower_complex, ctxt)
  {}

  /* opt_pass methods: */
  opt_pass * clone () { return new pass_lower_complex (m_ctxt); }
  virtual unsigned int execute (function *) { return tree_lower_complex (); }

}; // class pass_lower_complex

} // anon namespace

gimple_opt_pass *
make_pass_lower_complex (gcc::context *ctxt)
{
  return new pass_lower_complex (ctxt);
}


namespace {

const pass_data pass_data_lower_complex_O0 =
{
  GIMPLE_PASS, /* type */
  "cplxlower0", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_NONE, /* tv_id */
  PROP_cfg, /* properties_required */
  PROP_gimple_lcx, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  TODO_update_ssa, /* todo_flags_finish */
};

class pass_lower_complex_O0 : public gimple_opt_pass
{
public:
  pass_lower_complex_O0 (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_lower_complex_O0, ctxt)
  {}

  /* opt_pass methods: */
  virtual bool gate (function *fun)
    {
      /* With errors, normal optimization passes are not run.  If we don't
	 lower complex operations at all, rtl expansion will abort.  */
      return !(fun->curr_properties & PROP_gimple_lcx);
    }

  virtual unsigned int execute (function *) { return tree_lower_complex (); }

}; // class pass_lower_complex_O0

} // anon namespace

gimple_opt_pass *
make_pass_lower_complex_O0 (gcc::context *ctxt)
{
  return new pass_lower_complex_O0 (ctxt);
}
