/* Lower complex number operations to scalar operations.
   Copyright (C) 2004-2022 Free Software Foundation, Inc.

This file is part of GCC.

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

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

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

#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"
#include "gimple-fold.h"
#include "diagnostic-core.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:
		/* When expand_complex_move would trigger make sure we
		   perform lowering even when there is no actual complex
		   operation.  This helps consistency and vectorization.  */
		if (TREE_CODE (TREE_TYPE (gimple_op (stmt, 0))) == COMPLEX_TYPE)
		  saw_a_complex_op = true;
		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 || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (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);

  if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
    return SSA_PROP_VARYING;

  /* 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;
      copy_warning (r, orig);
    }
  else
    {
      DECL_IGNORED_P (r) = 1;
      suppress_warning (r);
    }

  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_CODE (rhs) == COMPLEX_CST)
	   && !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;
  gimple_seq stmts = NULL;
  location_t loc = gimple_location (gsi_stmt (*gsi));

  switch (PAIR (al, bl))
    {
    case PAIR (ONLY_REAL, ONLY_REAL):
      rr = gimple_build (&stmts, loc, code, inner_type, ar, br);
      ri = ai;
      break;

    case PAIR (ONLY_REAL, ONLY_IMAG):
      rr = ar;
      if (code == MINUS_EXPR)
	ri = gimple_build (&stmts, loc, MINUS_EXPR, inner_type, ai, bi);
      else
	ri = bi;
      break;

    case PAIR (ONLY_IMAG, ONLY_REAL):
      if (code == MINUS_EXPR)
	rr = gimple_build (&stmts, loc, MINUS_EXPR, inner_type, ar, br);
      else
	rr = br;
      ri = ai;
      break;

    case PAIR (ONLY_IMAG, ONLY_IMAG):
      rr = ar;
      ri = gimple_build (&stmts, loc, code, inner_type, ai, bi);
      break;

    case PAIR (VARYING, ONLY_REAL):
      rr = gimple_build (&stmts, loc, code, inner_type, ar, br);
      ri = ai;
      break;

    case PAIR (VARYING, ONLY_IMAG):
      rr = ar;
      ri = gimple_build (&stmts, loc, code, inner_type, ai, bi);
      break;

    case PAIR (ONLY_REAL, VARYING):
      if (code == MINUS_EXPR)
	goto general;
      rr = gimple_build (&stmts, loc, code, inner_type, ar, br);
      ri = bi;
      break;

    case PAIR (ONLY_IMAG, VARYING):
      if (code == MINUS_EXPR)
	goto general;
      rr = br;
      ri = gimple_build (&stmts, loc, code, inner_type, ai, bi);
      break;

    case PAIR (VARYING, VARYING):
    general:
      rr = gimple_build (&stmts, loc, code, inner_type, ar, br);
      ri = gimple_build (&stmts, loc, code, inner_type, ai, bi);
      break;

    default:
      gcc_unreachable ();
    }

  gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
  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_seq *stmts, location_t loc,
					  tree type, tree ar, tree ai,
					  tree br, tree bi,
					  tree *rr, tree *ri)
{
  tree t1, t2, t3, t4;

  t1 = gimple_build (stmts, loc, MULT_EXPR, type, ar, br);
  t2 = gimple_build (stmts, loc, MULT_EXPR, type, ai, bi);
  t3 = gimple_build (stmts, loc, 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 = gimple_build (stmts, loc, MULT_EXPR, type, ai, br);

  *rr = gimple_build (stmts, loc, MINUS_EXPR, type, t1, t2);
  *ri = gimple_build (stmts, loc, 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);
  location_t loc = gimple_location (gsi_stmt (*gsi));
  gimple_seq stmts = NULL;

  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 = gimple_build (&stmts, loc, 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 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ai, br);
      break;

    case PAIR (ONLY_IMAG, ONLY_IMAG):
      rr = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ai, bi);
      rr = gimple_build (&stmts, loc, NEGATE_EXPR, inner_type, rr);
      ri = ar;
      break;

    case PAIR (VARYING, ONLY_REAL):
      rr = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ar, br);
      ri = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ai, br);
      break;

    case PAIR (VARYING, ONLY_IMAG):
      rr = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ai, bi);
      rr = gimple_build (&stmts, loc, NEGATE_EXPR, inner_type, rr);
      ri = gimple_build (&stmts, loc, 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;
	    }

	  if (!HONOR_NANS (inner_type))
	    {
	      /* If we are not worrying about NaNs expand to
		 (ar*br - ai*bi) + i(ar*bi + br*ai) directly.  */
	      expand_complex_multiplication_components (&stmts, loc, inner_type,
							ar, ai, br, bi,
							&rr, &ri);
	      break;
	    }

	  /* 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 (&stmts, loc,
						    inner_type, ar, ai,
						    br, bi, &tmpr, &tmpi);
	  gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
	  stmts = NULL;

	  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);
	  gimple_seq stmts2 = NULL;
	  tree cond_real = gimple_build (&stmts2, loc, REALPART_EXPR,
					 inner_type, libcall_res);
	  tree cond_imag = gimple_build (&stmts2, loc, IMAGPART_EXPR,
					 inner_type, libcall_res);
	  gsi_insert_seq_before (&cond_bb_gsi, stmts2, GSI_SAME_STMT);

	  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 (&stmts, loc,
						  inner_type, ar, ai,
						  br, bi, &rr, &ri);
      break;

    default:
      gcc_unreachable ();
    }

  gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
  update_complex_assignment (gsi, rr, ri);
}

/* Keep this algorithm in sync with fold-const.cc: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)
{
  gimple_seq stmts = NULL;
  location_t loc = gimple_location (gsi_stmt (*gsi));
  tree rr, ri, div, t1, t2, t3;

  t1 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, br, br);
  t2 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, bi, bi);
  div = gimple_build (&stmts, loc, PLUS_EXPR, inner_type, t1, t2);

  t1 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ar, br);
  t2 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ai, bi);
  t3 = gimple_build (&stmts, loc, PLUS_EXPR, inner_type, t1, t2);
  rr = gimple_build (&stmts, loc, code, inner_type, t3, div);

  t1 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ai, br);
  t2 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ar, bi);
  t3 = gimple_build (&stmts, loc, MINUS_EXPR, inner_type, t1, t2);
  ri = gimple_build (&stmts, loc, code, inner_type, t3, div);

  gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
  update_complex_assignment (gsi, rr, ri);
}

/* Keep this algorithm in sync with fold-const.cc: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;
  gimple_seq stmts = NULL;
  location_t loc = gimple_location (gsi_stmt (*gsi));

  /* Examine |br| < |bi|, and branch.  */
  t1 = gimple_build (&stmts, loc, ABS_EXPR, inner_type, br);
  t2 = gimple_build (&stmts, loc, ABS_EXPR, inner_type, bi);
  compare = gimple_build (&stmts, loc,
			  LT_EXPR, boolean_type_node, t1, t2);

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

      gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
      stmts = NULL;
      stmt = gimple_build_cond (NE_EXPR, compare, boolean_false_node,
				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);
    }
  else
    {
      gimple_seq_discard (stmts);
      stmts = NULL;
    }

  /* 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 = gimple_build (&stmts, loc, code, inner_type, br, bi);

      t1 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, br, ratio);
      div = gimple_build (&stmts, loc, PLUS_EXPR, inner_type, t1, bi);

      t1 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ar, ratio);
      tr = gimple_build (&stmts, loc, PLUS_EXPR, inner_type, t1, ai);

      t1 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ai, ratio);
      ti = gimple_build (&stmts, loc, MINUS_EXPR, inner_type, t1, ar);

      tr = gimple_build (&stmts, loc, code, inner_type, tr, div);
      ti = gimple_build (&stmts, loc, code, inner_type, ti, div);
      gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
      stmts = NULL;

     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 = gimple_build (&stmts, loc, code, inner_type, bi, br);

      t1 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, bi, ratio);
      div = gimple_build (&stmts, loc, PLUS_EXPR, inner_type, t1, br);

      t1 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ai, ratio);
      tr = gimple_build (&stmts, loc, PLUS_EXPR, inner_type, t1, ar);

      t1 = gimple_build (&stmts, loc, MULT_EXPR, inner_type, ar, ratio);
      ti = gimple_build (&stmts, loc, MINUS_EXPR, inner_type, ai, t1);

      tr = gimple_build (&stmts, loc, code, inner_type, tr, div);
      ti = gimple_build (&stmts, loc, code, inner_type, ti, div);
      gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
      stmts = NULL;

     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;
  gimple_seq stmts = NULL;
  location_t loc = gimple_location (gsi_stmt (*gsi));

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

    case PAIR (ONLY_REAL, ONLY_IMAG):
      rr = ai;
      ri = gimple_build (&stmts, loc, code, inner_type, ar, bi);
      ri = gimple_build (&stmts, loc, NEGATE_EXPR, inner_type, ri);
      break;

    case PAIR (ONLY_IMAG, ONLY_REAL):
      rr = ar;
      ri = gimple_build (&stmts, loc, code, inner_type, ai, br);
      break;

    case PAIR (ONLY_IMAG, ONLY_IMAG):
      rr = gimple_build (&stmts, loc, code, inner_type, ai, bi);
      ri = ar;
      break;

    case PAIR (VARYING, ONLY_REAL):
      rr = gimple_build (&stmts, loc, code, inner_type, ar, br);
      ri = gimple_build (&stmts, loc, code, inner_type, ai, br);
      break;

    case PAIR (VARYING, ONLY_IMAG):
      rr = gimple_build (&stmts, loc, code, inner_type, ai, bi);
      ri = gimple_build (&stmts, loc, code, inner_type, ar, bi);
      ri = gimple_build (&stmts, loc, 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 ();
    }

  gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
  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;
  gimple_seq stmts = NULL;
  location_t loc = gimple_location (gsi_stmt (*gsi));

  rr = gimple_build (&stmts, loc, NEGATE_EXPR, inner_type, ar);
  ri = gimple_build (&stmts, loc, NEGATE_EXPR, inner_type, ai);

  gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
  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;
  gimple_seq stmts = NULL;
  location_t loc = gimple_location (gsi_stmt (*gsi));

  ri = gimple_build (&stmts, loc, NEGATE_EXPR, inner_type, ai);

  gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
  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 = gsi_stmt (*gsi);
  gimple_seq stmts = NULL;
  location_t loc = gimple_location (stmt);

  cr = gimple_build (&stmts, loc, code, boolean_type_node, ar, br);
  ci = gimple_build (&stmts, loc, code, boolean_type_node, ai, bi);
  cc = gimple_build (&stmts, loc,
		     (code == EQ_EXPR ? BIT_AND_EXPR : BIT_IOR_EXPR),
		     boolean_type_node, cr, ci);
  gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);

  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;
  bool diagnosed_p = false;

  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)
	{
	  if (gimple_asm_nlabels (stmt) > 0)
	    {
	      if (!diagnosed_p)
		{
		  sorry_at (gimple_location (stmt),
			    "%<asm goto%> with complex typed outputs");
		  diagnosed_p = true;
		}
	      /* Make sure to not ICE later, see PR105165.  */
	      tree zero = build_zero_cst (TREE_TYPE (TREE_TYPE (op)));
	      set_component_ssa_name (op, false, zero);
	      set_component_ssa_name (op, true, zero);
	      continue;
	    }
	  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, true);

  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, true);

  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 () final override { return new pass_lower_complex (m_ctxt); }
  unsigned int execute (function *) final override
  {
    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: */
  bool gate (function *fun) final override
    {
      /* 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);
    }

  unsigned int execute (function *) final override
  {
    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);
}
